I'm creating a Blaze View with the following call:
我正在使用以下调用创建Blaze View:
Blaze.renderWithData(Template.my_template, myobj._id, html.node());
my_template
looks like this:
my_template看起来像这样:
<template name="my_template">
{{> Template.dynamic template=whichTemplate data=sdata}}
</template>
The sdata helper looks like this:
sdata助手看起来像这样:
sdata: function() {
return Doodads.findOne({_id: this});
}
Which fails with the following error:
哪个失败,出现以下错误:
Exception in template helper: TypeError: selKey.substr is not a function
模板助手中的异常:TypeError:selKey.substr不是函数
If I do console.log(this)
within that helper, I get:
如果我在该帮助器中执行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"}
To correct the problem, I can change the findOne()
line to:
要解决此问题,我可以将findOne()行更改为:
return Doodads.findOne({_id: ""+this});
Which works as expected.
哪个按预期工作。
I am posting this question to help myself (and others) understand what is going on here.
我发布这个问题是为了帮助自己(和其他人)了解这里发生了什么。
Mainly I want to know:
主要是我想知道:
- Why is there difference between using a
String{...}
object and a regular string for this call (i.e, why doesn't the selector key object have asubstr()
method when I'm using a different/weird selector value)? - Why does the
_id
property show up as this weirdString{...}
object as the template datathis
when the_id
property is usually just a string? Or is it not usually and I've just never noticed?
为什么在此调用中使用String {...}对象和常规字符串之间存在差异(即,当我使用不同/奇怪的选择器值时,为什么选择器键对象没有substr()方法) ?
当_id属性通常只是一个字符串时,为什么_id属性显示为这个奇怪的String {...}对象作为模板数据?或者通常不是,我从来没有注意到?
I've solved the problem with the ""+this
hack, but is there a more proper way to do this?
我用“”+这个黑客解决了这个问题,但有没有更合适的方法呢?
2 个解决方案
#1
0
what is wrong?
According to the Blaze API docs, the signature is:
根据Blaze API文档,签名是:
Blaze.renderWithData(templateOrView, data, parentNode, [nextNode], [parentView])
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.
要使用的数据上下文,或返回数据上下文的函数。如果提供了一个功能,它将被反应性地重新运行。
The data context, in your case, should be an object which includes a whichTemplate
property and some id
that you can use in your helper.
在您的情况下,数据上下文应该是一个对象,其中包含一个whichTemplate属性和一些可以在助手中使用的id。
Blaze.renderWithData(Template.my_template, {
_id: myId,
whichTemplate: someTemplateName
}, someNode);
or, instead of a data object, pass a function that will be reactively re-run.
或者,而不是数据对象,传递将被反应重新运行的函数。
With this setup, your helper code should be something like:
使用此设置,您的帮助程序代码应类似于:
sdata: function() {
return Doodads.findOne(this._id);
}
source of the error you were seeing
If you are interested in the cause of the error you were getting, here's what is going on:
如果你对你得到的错误的原因感兴趣,这是正在发生的事情:
In blaze, the countext is bound to the template helper's this
reference using Function.protptype.apply(thisArg, [argsArray])
(in this line).
在大火中,countext使用Function.protptype.apply(thisArg,[argsArray])(在此行中)绑定到模板助手的此引用。
According to the EcmaScript standard, if thisArg
is a primitive, it will be boxed.
根据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.
这个值的价值提供给乐趣。请注意,这可能不是方法看到的实际值:如果方法是非严格模式代码中的函数,则null和undefined将替换为全局对象,并且原始值将被加框。
(source: MDN)
This causes a String
object, which does not have a substr
method, be transferred to the MiniMongo.Collection
's find()
method, which fails here.
这会导致没有substr方法的String对象被转移到MiniMongo.Collection的find()方法,该方法在此处失败。
#2
0
If your data is created from some other source than a Meteor subscription, it could be that your _id is a MongoDB ObjectId, which is not a string.
如果您的数据是从Meteor订阅之外的其他来源创建的,则可能是您的_id是MongoDB ObjectId,它不是字符串。
Have a look in the Mongo shell, if you do a .findOne on the myobj
object and it shows up looking something like
看看Mongo shell,如果你在myobj对象上做一个.findOne,它会显示出像
"_id" : ObjectId("57cd946429bca10300f0fd55")
#1
0
what is wrong?
According to the Blaze API docs, the signature is:
根据Blaze API文档,签名是:
Blaze.renderWithData(templateOrView, data, parentNode, [nextNode], [parentView])
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.
要使用的数据上下文,或返回数据上下文的函数。如果提供了一个功能,它将被反应性地重新运行。
The data context, in your case, should be an object which includes a whichTemplate
property and some id
that you can use in your helper.
在您的情况下,数据上下文应该是一个对象,其中包含一个whichTemplate属性和一些可以在助手中使用的id。
Blaze.renderWithData(Template.my_template, {
_id: myId,
whichTemplate: someTemplateName
}, someNode);
or, instead of a data object, pass a function that will be reactively re-run.
或者,而不是数据对象,传递将被反应重新运行的函数。
With this setup, your helper code should be something like:
使用此设置,您的帮助程序代码应类似于:
sdata: function() {
return Doodads.findOne(this._id);
}
source of the error you were seeing
If you are interested in the cause of the error you were getting, here's what is going on:
如果你对你得到的错误的原因感兴趣,这是正在发生的事情:
In blaze, the countext is bound to the template helper's this
reference using Function.protptype.apply(thisArg, [argsArray])
(in this line).
在大火中,countext使用Function.protptype.apply(thisArg,[argsArray])(在此行中)绑定到模板助手的此引用。
According to the EcmaScript standard, if thisArg
is a primitive, it will be boxed.
根据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.
这个值的价值提供给乐趣。请注意,这可能不是方法看到的实际值:如果方法是非严格模式代码中的函数,则null和undefined将替换为全局对象,并且原始值将被加框。
(source: MDN)
This causes a String
object, which does not have a substr
method, be transferred to the MiniMongo.Collection
's find()
method, which fails here.
这会导致没有substr方法的String对象被转移到MiniMongo.Collection的find()方法,该方法在此处失败。
#2
0
If your data is created from some other source than a Meteor subscription, it could be that your _id is a MongoDB ObjectId, which is not a string.
如果您的数据是从Meteor订阅之外的其他来源创建的,则可能是您的_id是MongoDB ObjectId,它不是字符串。
Have a look in the Mongo shell, if you do a .findOne on the myobj
object and it shows up looking something like
看看Mongo shell,如果你在myobj对象上做一个.findOne,它会显示出像
"_id" : ObjectId("57cd946429bca10300f0fd55")