Iron-Router模板中的上下文
我无法准确地了解 流星用Iron-Router调用的模板中可作为上下文使用的内容以及这些东西如何继承.
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:
- 内置助手
-
Handlebars.registerHelper(...)
-
Template.myTemplate.myVar/myHelper = ...
-
Template.myTemplate.helpers({ ... })
-
data: { ... }
路由内(Router.map) - 与
#each
有关系吗? - 与
#with
有关系吗?
- 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?
我想我对最初为模板提供上下文的标准方法有些困惑.还涉及诸如#each
和#with
之类的控制结构内部发生的情况.
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
.
澄清会很棒!
IronRouter使用RouteController.data的结果作为当前数据上下文来呈现您的模板.
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
});
在此示例中,IronRouter将使用具有this.params._id作为数据上下文的帖子来呈现"viewPost"模板.
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 ?
有2种方法:
{{#with myContext}}
{{> myTemplate}}
{{/with}}
{{> myTemplate myContext}}
如您所见,#with控件结构设置当前数据上下文. #each结构在游标(或数组)上进行迭代,并将当前数据上下文设置为当前获取的文档(或当前单元格).
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"}];
}
});
更新:您能否添加有关继承的注释?例如,如果我嵌套了#each块,变量是否会级联?
我想到了这个例子:
<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"
}];
}
});
如果运行此示例,则会注意到您无法在内容"中访问parentProperty,因为默认的#each帮助程序会使用提供的新上下文覆盖父数据上下文.
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.
您可以使用以下语法在嵌套的#each块中访问parentProperty:../this.parentProperty,使人联想到UNIX父目录访问语法.
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.
但是,您不能在内容"模板中使用此语法,因为它与从其调用的每个结构的嵌套无关:您只能在实际嵌套的模板中使用../../parent语法发生.
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.
如果要访问内容模板中的parentPropery,则必须使用父上下文扩充当前数据上下文.
If we want to access the parentPropery in the content template, we must augment the current data context with the parent context.
为此,我们可以像这样注册一个新的#eachWithParent帮助器:
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;
});
现在,如果您使用此新帮助程序替换嵌套的#each,则可以访问内容"中的parentProperty.
Now if you replace the nested #each with this new helper, you will have access to parentProperty in "content".