Meteor js - 如何挂钩到递归模板的'render'事件?

时间:2014-01-23 17:25:20

标签: meteor handlebars.js

我有一种情况,我基于Mongodb树结构递归地渲染Handlebars,如下所示:

<template name='menu'>
    <ul class='menu'>
     {{#each topLevelChildren}}
        {{>menu-item}}
     {{/each}}
    </ul>
</template>

<template name='menu-item'>
  <li>{{name}}
    {{#if listChildren.count}}
    <ul>
        {{#each listChildren}}
           {{>menu-item}}
        {{/each}}
    </ul>
    {{/if}}
  </li>
</template>

mongodb文档看起来像这样:

{ _id : ObjectId("525eb7245359090f41b65106"),
  name : 'Foo',
  children : [  ObjectId("525eb60c5359090f41b65104"),   ObjectId("525eb6ca5359090f41b65105") ]
}

和listChildren只返回一个游标,其中包含父元素子数组中每个元素的完整文档。

我想在渲染树上做一些jquery化妆,但我似乎无法挂钩整个树的'rendered'事件,比如

Template.menu-completed.rendered = function(){
   // console.log('done!');
}

试试这个

Template.menu.rendered = function(){
    console.log($('menu li'));
}

这不仅不会返回正确的结果(括号中填充逗号),它还冻结了Web检查器(但不是应用程序......)。 任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:2)

这是一个有趣的问题:)

在当前版本的Meteor(0.7.x)中,rendered回调在首次渲染模板时调用一次,然后在模板内的任何部分重新渲染后再次调用。 (当Meteor 0.8 - shark分支或“Meteor UI” - 落地时,此行为将发生变化。)

我从来没有尝试递归地做事,但是很难分辨出你得到的回调实际上是为了父母。您可能想要尝试的一件事是在名为menu-parent的模板中启动递归渲染。这样,当第一次调用rendered回调时(并且只要加载了数据),就知道整个树都被渲染了。

但是,我怀疑可能有更好的方法来做到这一点。通常,您不应该使用jQuery来修改DOM元素上的类和属性,因为您会对Meteor正在做什么以及jQuery正在做什么感到困惑。你能用以下内容详细说明你想要实现的目标,我会更新我的答案吗?

  

我需要在完全渲染的模板中找到一个特定的锚标签并为其添加一个类......然后为每个父类添加一个类

答案 1 :(得分:1)

Petrov,您的代码实际上适用于我,只需对jquery部分进行一些小修改。但也许我误解了。这是我做的:

  1. 创建了一个全新的项目。
  2. 在.html中添加了您的模板并进行了细微更改:<li><span class="name">{{name}}</span>

  3. 创建了一个新的集合列表。

  4. Template.menu.topLevelChildren = function() { return List.find(); };
  5. 然后我添加了这个处理程序:

    Template.menu.rendered = function(e){
        $('.name').each(function(i, e) {
            console.log(e);
        });
    }
    

    现在,在渲染时,例如当新数据插入List集合时,我在控制台上得到一个打印输出:

    <span class=​"name">​second​</span>​
    <span class=​"name">​second2​</span>​
    <span class=​"name">​second21​</span>​
    <span class=​"name">​second22​</span>​
    <span class=​"name">​third​</span>​
    <span class=​"name">​third2​</span>​
    <span class=​"name">​third21​</span>​
    <span class=​"name">​third22​</span>​
    <span class=​"name">​third​</span>​
    <span class=​"name">​third2​</span>​
    <span class=​"name">​third21​</span>​
    <span class=​"name">​third22​</span>​
    

    这只是我添加的树元素的平面列表(second2嵌套在second中,second2x嵌套在second2等) 。所以根据我的理解,你可以从jquery中选择回来,找到你正在寻找的标签并根据需要改变它的类。如果我误解了什么,请告诉我。

    完整的代码如下。


    的test.html:

    <head>
      <title>test</title>
    </head>
    
    <body>
      {{> menu }}
    </body>
    
    <template name='menu'>
        <ul class='menu'>
         {{#each topLevelChildren}}
            {{>menu-item}}
         {{/each}}
        </ul>
    </template>
    
    <template name='menu-item'>
      <li><span class="name">{{name}}</span>
        <ul>
        {{#each children}}
        {{>menu-item}}
        {{/each}}
        </ul>
      </li>
    </template>
    

    test.js:

    List = new Meteor.Collection("List");
    
    if (Meteor.isClient) {
        Template.menu.topLevelChildren = function() {
            return List.find();
        };
    
        Template.menu.rendered = function(e){
            $('.name').each(function(i, e) {
                console.log(e);
            });
        }
    }
    
    if (Meteor.isServer) {
      Meteor.startup(function () {
        // code to run on server at startup
      });
    }