Iron-Router模板中的上下文

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".