【问题标题】:Meteor js - how to hook into the 'rendered' event of a recursive template?Meteor js - 如何挂钩递归模板的“渲染”事件?
【发布时间】:2014-02-02 09:19:06
【问题描述】:

我遇到了一种情况,我正在基于 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 化妆,但我似乎无法连接到整个树的“渲染”事件,比如

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

试试这个

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

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

【问题讨论】:

  • 你想做什么样的化妆?在大多数情况下,您可以通过 1) 将 jquery 改进分别应用于每个模板或 2) 合并模板来避免此问题。
  • 我需要在完全渲染的模板中找到一个特定的锚标记并为其添加一个类...然后为其每个父级添加一个类
  • 如果当前项目是正确的(锚所有者),您是否尝试使用自定义车把助手并执行一些 JQuery?看看这颗陨石github.com/raix/Meteor-handlebar-helpers

标签: meteor handlebars.js


【解决方案1】:

这是一个有趣的问题:)

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

我从未尝试过递归地做事,但很难判断你得到的回调实际上是针对父级的。您可能想尝试的一件事是在名为 menu-parent 的模板中开始递归渲染。这样,当第一次调用 rendered 回调时(并且只要您的数据被加载),您就知道整个树都被渲染了。

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

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

【讨论】:

  • 感谢安德鲁的精彩回复!我需要做的是建立一个树形菜单,其外观适应当前的 url。因此,例如,如果 url 是“纽约市”,那么我需要找到锚标签“new_york_city”,然后一直向其每个父级添加一个类:“new_york”、“usa”、“north_america” (例如)。我使用的数据实际上是动态的,所以我不能只为整个事物呈现一个静态的嵌套无序列表
  • 我一直在查看鲨鱼分支,似乎我可以在不重新渲染任何内容的情况下更改类,这将使我的问题消失......
  • 在这种情况下尝试meteor --release template-engine-preview-10.1,其中template-engine-preview-10.1 是在github.com/meteor/meteor/releases 找到的最新模板引擎(鲨鱼)版本,看看您是否可以让这些类以这种方式工作。
  • 谢谢安德鲁,我非常感谢您的建议 - 我赞成您的回复,但由于我们没有真正解决最初的问题,我认为赏金可能不合理。想讨论可以私信我。
  • @Petrov 你可以为所欲为 - SO 上没有 PM。
【解决方案2】:

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

  1. 创建了一个全新的项目。
  2. 在 .html 中添加了您的模板,稍作更改:&lt;li&gt;&lt;span class="name"&gt;{{name}}&lt;/span&gt;

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

  4. Template.menu.topLevelChildren = function() { return List.find(); };

然后我添加了这个处理程序:

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
  });
}

【讨论】:

  • @Petrov:这能回答你的问题吗?或者您是否也想知道 jquery 部分?
  • @Petrov:你得到了一笔赏金,向人们表明你真的很想在这里得到一些帮助。如果您至少让我们知道您最终是如何解决问题的,以及为什么建议的解决方案都不适合您,我将不胜感激。
猜你喜欢
  • 1970-01-01
  • 2014-01-31
  • 2014-12-08
  • 1970-01-01
  • 2016-11-13
  • 1970-01-01
  • 2014-12-12
  • 1970-01-01
  • 2015-09-15
相关资源
最近更新 更多