设置Meteor JS Helper的返回值,将其动态注入模板中

Set the return value of Meteor JS Helper, inject this dynamically into template

本文关键字:动态 注入 JS Meteor Helper 返回值 设置      更新时间:2023-09-26

编辑:

给出以下答案,使用Meteor Deps似乎是理想的选择,因为我想在两个不同的模板之间共享数据,并且它应该对发生的任何变化做出反应。

澄清一下:我的数据来源是Template.reactiveTable,目的地是Template.buttons。当reactiveTable中的数据发生变化时,我希望按钮能够反映这一点。

结束编辑

我希望根据表的内容设置buttons的值(特别是<h1>的值)。

buttons.html:

  <template name="buttons">
    {{#each testButtons }}
       <button id="{{ name }}">{{ name }}</button>
    {{/each}}
  </template>

通过这种硬编码,它可以按预期工作(两个按钮分别标记为Alice和Bob

UI.registerHelper('testButtons', function () {
        return [ 
          { name: "Alice" }, 
          { name: "Bob" } 
        ]
    }
)

模板愉快地接受并呈现这个对象数组。但是,当我动态生成对象数组时,不要这样做。

目标:对于h1标签中包含的每个唯一单词,生成一个按钮(几乎像博客标签)。

通过用下面的代码片段替换我的助手代码(使用jquery解析<h1>标记,生成要发送到模板的数组)。

假设html是:

  <h1>foo</h1>
  <h1>bar</h1>
  <h1>baz</h1>

然后在控制台中运行下面的代码段,将根据需要创建uniqStrings = [ "foo", "bar", "baz"];

$( 'h1' ).map(function () {
  var words = [];
  words.push($(this).text());
  uniqStrings = _.uniq(words);
});

然后如何将uniqStrings发送回我的按钮模板以渲染n= uniqStrings.length按钮?谢谢

假设这个html:

<body>
  <h1>Alice</h1>
  <h1>Bob</h1>
  {{> buttons}}
</body>
<template name="buttons">
  {{#each testButtons }}
    <button id="{{ name }}">{{ name }}</button>
  {{/each}}
</template>

你可以让它与这个实现一起工作:

Template.buttons.helpers({
  testButtons: function() {
    var words = UI._templateInstance().state.get('words');
    return _.map(words, function(word) {
      return {name: word};
    });
  }
});
Template.buttons.rendered = function() {
  var words = $('h1').map(function() {
    return $(this).text();
  });
  this.state.set('words', _.uniq(words));
};
Template.buttons.created = function() {
  this.state = new ReactiveDict;
};

注意:meteor add reactive-dict

创建buttons模板时,初始化其自身的内部反应状态。呈现后,它将使用页面上所有h1标记的文本填充该状态。由于该状态是被动的,因此它将导致testButtons运行并将正确格式化的数据返回到模板。有关更多详细信息,请参阅我在Scoped Reactivity上的帖子。

因为buttons模板使用作用域反应性,所以它可以在任何页面上随意使用多次,而无需修改父模板。

虽然我不完全清楚为什么要解析一个表的内容,然后在另一个表中呈现它(这就是你想要做的,不是吗?),但基本原理如下:

当模板的任何反应依赖项发生更改时,模板将重新提交。这意味着你需要:

  • 将有问题的数组存储在一个结构中,该结构在设计上是被动的(因此要么是minimongo,即客户端数据库),要么是会话变量
  • 使用一个单独的(反应性的)变量,它只是告诉模板需要在正确的时间重新提交

从应用程序结构的角度来看,后者可能不太好,但最容易举例说明:

var renderDep = new Deps.Dependency(),
    words = [];
UI.registerHelper('testButtons', function () {
    renderDep.depend();
    return words;
});

然后每当你打电话:

$( 'h1' ).map(function () {
    words = [];
    words.push($(this).text());
    uniqStrings = _.uniq(words);       
});  

请务必致电:

renderDep.changed();

并且它的所有依赖项(即模板助手)将重新运行并返回新的words内容。