简体   繁体   English

为什么不能将字符串作为数据参数传递给Blaze.renderWithData()?

[英]Why can't I pass a string as the data argument to Blaze.renderWithData()?

I'm creating a Blaze View with the following call: 我正在通过以下调用创建Blaze视图:

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 (ie, why doesn't the selector key object have a substr() method when I'm using a different/weird selector value)? 为什么在此调用中使用String{...}对象和常规字符串之间会有区别(即,当我使用其他/奇怪的选择器值时,为什么选择器键对象没有substr()方法) ?
  • Why does the _id property show up as this weird String{...} object as the template data this when the _id property is usually just a string? 为什么_id属性显示为这个奇怪的String{...}对象作为模板数据, this时候_id属性通常只是一个字符串? Or is it not usually and I've just never noticed? 还是不是通常,而我只是从未注意到?

I've solved the problem with the ""+this hack, but is there a more proper way to do this? 我已经使用""+this hack解决了问题,但是还有更合适的方法吗?

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 如果您在myobj对象上执行.findOne,那么请看一下Mongo shell,它看起来像

"_id" : ObjectId("57cd946429bca10300f0fd55")

what is wrong? 怎么了?

According to the Blaze API docs , the signature is: 根据Blaze API文档 ,签名为:

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 ). Function.protptype.apply(thisArg, [argsArray])使用Function.protptype.apply(thisArg, [argsArray]) (在此行中 )将countext绑定到模板助手的this引用。

According to the EcmaScript standard, if thisArg is a primitive, it will be boxed. 根据EcmaScript标准,如果thisArg是基元,则将其装箱。

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 ) (来源: 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.Collectionfind()方法,该方法在此处失败

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Meteor Blaze.renderWithData(),如何传递函数 - Meteor Blaze.renderWithData(), how to pass functions 流星大火的renderwithdata通过自动格式化将文档传递到模板 - meteor blaze renderwithdata pass document to template with autoform 流星大火renderWithData - Meteor Blaze renderWithData 为什么我不能在Javascript函数中传递字符串作为参数? - Why can't I pass a string as a parameter in a Javascript function? 为什么我无法在Chrome(和Safari)中将console.log作为回调参数传递? - Why I can't pass console.log as a callback argument in Chrome (and Safari)? 为什么我不能将“window.location.reload”作为参数传递给 setTimeout? - Why can't I pass “window.location.reload” as an argument to setTimeout? 我找不到为什么我不能将数据传递给道具 - I can't find why I can't pass data to props 我可以将字符串参数传递给 onclick javascript function 吗? - Can I pass a string argument to an onclick javascript function? 得到一个未终止的字符串文字错误..我可以让它通过,但无法弄清楚为什么 - Getting an unterminated string literal error..I can make it pass, but can't figure out why 传递空格键的当前值:作为流星/火焰中新辅助函数的参数 - pass current value of spacebars:this as argument to new helper in meteor/blaze
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM