为什么我不能将字符串作为数据参数传递给 Blaze.renderWithData()?
Why can't I pass a string as the data argument to Blaze.renderWithData()?
我正在使用以下调用创建 Blaze 视图:
Blaze.renderWithData(Template.my_template, myobj._id, html.node());
my_template
看起来像这样:
<template name="my_template">
{{> Template.dynamic template=whichTemplate data=sdata}}
</template>
sdata 助手看起来像这样:
sdata: function() {
return Doodads.findOne({_id: this});
}
失败并出现以下错误:
Exception in template helper: TypeError: selKey.substr is not a function
如果我在该助手中执行 console.log(this)
,我得到:
String {0: "N", 1: "7", 2: "j", 3: "o", 4: "y", 5: "g", 6: "w", 7: "P", 8: "g", 9: "e", 10: "s", 11: "R", 12: "f", 13: "w", 14: "q", 15: "o", 16: "7", length: 17, [[PrimitiveValue]]: "N7joygwPgesRfwqo7"}
要更正此问题,我可以将 findOne()
行更改为:
return Doodads.findOne({_id: ""+this});
按预期工作。
我发布这个问题是为了帮助我自己(和其他人)理解这里发生的事情。
我主要想知道:
- 为什么使用
String{...}
对象和此调用的常规字符串之间存在差异(即,为什么选择器键对象没有 substr()
方法,而我使用different/weird 选择器值)?
- 为什么
_id
属性 显示为这个奇怪的 String{...}
对象作为模板数据 this
而 _id
属性通常只是一个字符串?还是不经常而且我从来没有注意到?
我已经用 ""+this
hack 解决了这个问题,但是有更合适的方法吗?
如果您的数据是从 Meteor 订阅以外的其他来源创建的,则可能是您的 _id 是 MongoDB ObjectId,它不是字符串。
看看 Mongo shell,如果你在 myobj
对象上执行 .findOne,它看起来像
"_id" : ObjectId("57cd946429bca10300f0fd55")
怎么了?
根据Blaze API docs,签名是:
Blaze.renderWithData(templateOrView, data, parentNode, [nextNode], [parentView])
data Object or Function
The data context to use, or a function returning a data context. If a function is provided, it will be reactively re-run.
在您的情况下,数据上下文应该是一个对象,其中包含一个 whichTemplate
属性 和一些您可以在助手中使用的 id
。
Blaze.renderWithData(Template.my_template, {
_id: myId,
whichTemplate: someTemplateName
}, someNode);
或者,传递一个函数,而不是数据对象,该函数将被反应性地重新运行。
使用此设置,您的帮助程序代码应该类似于:
sdata: function() {
return Doodads.findOne(this._id);
}
您看到的错误来源
如果您对所遇到错误的原因感兴趣,请查看正在发生的事情:
在 blaze 中,countext 使用 Function.protptype.apply(thisArg, [argsArray])
(在 this line 中)绑定到模板助手的 this
引用。
根据EcmaScript标准,如果thisArg
是原始类型,它会被装箱。
thisArg
The value of this provided for the call to fun. Note that this may not be the actual value seen by the method: if the method is a function in non-strict mode code, null and undefined will be replaced with the global object, and primitive values will be boxed.
(source: MDN)
这会导致没有 substr
方法的 String
对象被转移到 MiniMongo.Collection
的 find()
方法,fails here.
我正在使用以下调用创建 Blaze 视图:
Blaze.renderWithData(Template.my_template, myobj._id, html.node());
my_template
看起来像这样:
<template name="my_template">
{{> Template.dynamic template=whichTemplate data=sdata}}
</template>
sdata 助手看起来像这样:
sdata: function() {
return Doodads.findOne({_id: this});
}
失败并出现以下错误:
Exception in template helper: TypeError: selKey.substr is not a function
如果我在该助手中执行 console.log(this)
,我得到:
String {0: "N", 1: "7", 2: "j", 3: "o", 4: "y", 5: "g", 6: "w", 7: "P", 8: "g", 9: "e", 10: "s", 11: "R", 12: "f", 13: "w", 14: "q", 15: "o", 16: "7", length: 17, [[PrimitiveValue]]: "N7joygwPgesRfwqo7"}
要更正此问题,我可以将 findOne()
行更改为:
return Doodads.findOne({_id: ""+this});
按预期工作。
我发布这个问题是为了帮助我自己(和其他人)理解这里发生的事情。
我主要想知道:
- 为什么使用
String{...}
对象和此调用的常规字符串之间存在差异(即,为什么选择器键对象没有substr()
方法,而我使用different/weird 选择器值)? - 为什么
_id
属性 显示为这个奇怪的String{...}
对象作为模板数据this
而_id
属性通常只是一个字符串?还是不经常而且我从来没有注意到?
我已经用 ""+this
hack 解决了这个问题,但是有更合适的方法吗?
如果您的数据是从 Meteor 订阅以外的其他来源创建的,则可能是您的 _id 是 MongoDB ObjectId,它不是字符串。
看看 Mongo shell,如果你在 myobj
对象上执行 .findOne,它看起来像
"_id" : ObjectId("57cd946429bca10300f0fd55")
怎么了?
根据Blaze API docs,签名是:
Blaze.renderWithData(templateOrView, data, parentNode, [nextNode], [parentView])
data Object or Function
The data context to use, or a function returning a data context. If a function is provided, it will be reactively re-run.
在您的情况下,数据上下文应该是一个对象,其中包含一个 whichTemplate
属性 和一些您可以在助手中使用的 id
。
Blaze.renderWithData(Template.my_template, {
_id: myId,
whichTemplate: someTemplateName
}, someNode);
或者,传递一个函数,而不是数据对象,该函数将被反应性地重新运行。
使用此设置,您的帮助程序代码应该类似于:
sdata: function() {
return Doodads.findOne(this._id);
}
您看到的错误来源
如果您对所遇到错误的原因感兴趣,请查看正在发生的事情:
在 blaze 中,countext 使用 Function.protptype.apply(thisArg, [argsArray])
(在 this line 中)绑定到模板助手的 this
引用。
根据EcmaScript标准,如果thisArg
是原始类型,它会被装箱。
thisArg
The value of this provided for the call to fun. Note that this may not be the actual value seen by the method: if the method is a function in non-strict mode code, null and undefined will be replaced with the global object, and primitive values will be boxed.
(source: MDN)
这会导致没有 substr
方法的 String
对象被转移到 MiniMongo.Collection
的 find()
方法,fails here.