Iron-Router 模板内的上下文 [英] Context inside templates with Iron-Router
问题描述
我无法确切地理解在 Meteor 和 Iron-Router 调用的模板中哪些内容可用作我的上下文——以及这些内容如何继承.
以下是我能想到的我可以在双花括号内引用的东西"的所有潜在来源:
- 内置助手
Handlebars.registerHelper(...)
Template.myTemplate.myVar/myHelper = ...
Template.myTemplate.helpers({ ... })
data: { ... }
路由内(Router.map)- 与
#each
有什么关系? - 与
#with
有什么关系?
我忘记了什么吗?有没有全局变量?
我想我对首先为模板提供上下文的标准方式有些困惑.还有关于#each
和#with
等控制结构内部发生的事情.
澄清会很棒!
IronRouter 使用 RouteController.data 的结果作为当前数据上下文呈现您的模板.
<div><h1>{{title}}</h1><p>{{content}}</p>
模板>var PostsController=RouteController.extend({模板:viewPost",等待:功能(){return Meteor.subscribe("postsById",this.params._id);},数据:功能(){返回 Posts.findOne(this.params._id);}});this.route("viewPost",{路径:"/posts/:_id",控制器:PostsController});
在这个例子中,IronRouter 将使用具有 this.params._id 作为数据上下文的帖子呈现viewPost"模板.
首先为模板提供上下文的标准方法是什么?
有两种方式:
{{#with myContext}}{{>我的模板}}{{/和}}{{>myTemplate myContext}}
如您所见,#with 控制结构设置当前数据上下文.#each 结构遍历 Cursor(或数组)并将当前数据上下文设置为当前获取的文档(或当前单元格).
{{#每个帖子}}<h1>{{title}}</h1>{{/每个}}模板>Template.postsList.helpers({帖子:功能(){//游标返回 Posts.find();//大批return [{title:"Title 1"},{title:"Title 2"},{title:"Title 3"}];}});
更新:您能否添加有关继承的注释?例如,如果我嵌套了 #each 块,变量是否级联?
我想出了这个例子:
<ul>{{#each parentContexts}}{{>孩子}}{{/每个}}模板><模板名称=孩子"><li><ul>{{#each childContexts}}{{>内容}}<p>../this.parentProperty = {{../this.parentProperty}}</p>{{/每个}}模板><模板名称=内容"><li><p>this.childProperty = {{this.childProperty}}</p><p>this.parentProperty = {{this.parentProperty}}</p>模板>Template.parent.helpers({父上下文:函数(){返回 [{父属性:父 1"},{父属性:父 2"}];}});Template.child.helpers({childContexts:函数(){返回 [{childProperty:"孩子 1"},{childProperty:"child 2"}];}});
如果您运行此示例,您会注意到您无法访问内容"中的 parentProperty,因为默认的 #each 助手使用提供的新上下文覆盖父数据上下文.
您可以使用以下语法访问嵌套 #each 块中的 parentProperty:../this.parentProperty,这让人联想到 UNIX 父目录访问语法.
但是,您不能在内容"模板中使用此语法,因为它与调用它的嵌套每个结构无关:您只能在实际嵌套的模板中使用 ../../parent 语法发生.
如果我们想访问内容模板中的 parentPropery,我们必须用父上下文扩充当前数据上下文.
为此,我们可以像这样注册一个新的#eachWithParent 助手:
Handlebars.registerHelper("eachWithParent",function(context,options){var parentContext=this;变量内容="";_.each(上下文,功能(项目){变量增强上下文 = _.extend(item,parentContext);内容+=options.fn(augmentedContext);});返回内容;});
现在,如果您用这个新的帮助器替换嵌套的 #each,您将可以访问内容"中的 parentProperty.
I'm having trouble understanding exactly what is available as my context in a template invoked by Meteor with Iron-Router – and how these things inherit.
Here are all the potential sources for "stuff I can refer to inside double curly braces" that I can think of:
- Built-in helpers
Handlebars.registerHelper(...)
Template.myTemplate.myVar/myHelper = ...
Template.myTemplate.helpers({ ... })
data: { ... }
inside route (Router.map)- Something to do with
#each
? - Something to do with
#with
?
Have I forgotten anything? Are there any global variables?
I guess I'm a bit confused about what the standard way is of giving the template a context in the first place. Also about what happens inside control structures such as #each
and #with
.
A clarification would be great!
IronRouter renders your template with the result of RouteController.data as the current data context.
<template name="viewPost">
<div>
<h1>{{title}}</h1>
<p>{{content}}</p>
</div>
</template>
var PostsController=RouteController.extend({
template:"viewPost",
waitOn:function(){
return Meteor.subscribe("postsById",this.params._id);
},
data:function(){
return Posts.findOne(this.params._id);
}
});
this.route("viewPost",{
path:"/posts/:_id",
controller:PostsController
});
In this example, IronRouter will render the "viewPost" template with the post having this.params._id as data context.
What is the standard way of giving a template a context in the first place ?
There is 2 ways :
{{#with myContext}}
{{> myTemplate}}
{{/with}}
{{> myTemplate myContext}}
As you can see, the #with control structure sets the current data context. The #each structure iterates over a Cursor (or an Array) and sets the current data context to the current fetched document (or the current cell).
<template name="postsList">
{{#each posts}}
<h1>{{title}}</h1>
{{/each}}
</template>
Template.postsList.helpers({
posts:function(){
// cursor
return Posts.find();
// array
return [{title:"Title 1"},{title:"Title 2"},{title:"Title 3"}];
}
});
UPDATE : Could you possibly add a note about inheritance ? For instance, if I have nested #each blocks, do variables cascade ?
I came up with this example :
<template name="parent">
<ul>
{{#each parentContexts}}
{{> child}}
{{/each}}
</ul>
</template>
<template name="child">
<li>
<ul>
{{#each childContexts}}
{{> content}}
<p>../this.parentProperty = {{../this.parentProperty}}</p>
{{/each}}
</ul>
</li>
</template>
<template name="content">
<li>
<p>this.childProperty = {{this.childProperty}}</p>
<p>this.parentProperty = {{this.parentProperty}}</p>
</li>
</template>
Template.parent.helpers({
parentContexts:function(){
return [{
parentProperty:"parent 1"
},{
parentProperty:"parent 2"
}];
}
});
Template.child.helpers({
childContexts:function(){
return [{
childProperty:"child 1"
},{
childProperty:"child 2"
}];
}
});
If you run this example, you'll notice that you can't access the parentProperty in "content" because the default #each helper OVERRIDES the parent data context with the new context provided.
You can access the parentProperty in the nested #each block using this syntax : ../this.parentProperty, which is reminiscent of the UNIX parent directory access syntax.
However you cannot use this syntax in the "content" template, because it is agnostic of the nested each structures it was called from : you can only use the ../../parent syntax in a template where the actual nesting happens.
If we want to access the parentPropery in the content template, we must augment the current data context with the parent context.
To do so, we can register a new #eachWithParent helper like this :
Handlebars.registerHelper("eachWithParent",function(context,options){
var parentContext=this;
var contents="";
_.each(context,function(item){
var augmentedContext=_.extend(item,parentContext);
contents+=options.fn(augmentedContext);
});
return contents;
});
Now if you replace the nested #each with this new helper, you will have access to parentProperty in "content".
这篇关于Iron-Router 模板内的上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!