初始化新对象时是否会在流星中触发新模板?

时间:2018-03-21 22:17:47

标签: meteor meteor-blaze

我正在构建一个页面,需要创建一个矩阵,其中数字或行和列是被动的(可以通过用户点击“添加行”等来改变它。)

我使用了一个函数来为客户端的每个单元格准备内容:

function prepareCells(rows, columns){
    let matrixContent = {};
    ...logics here...
    return matrixContent;
}

在客户中还有以下帮助者:

Template.matrix.helpers({

matrixContents(){
    const instance = Template.instance();
    let rows = instance.state.get("rows");
    let columns = instance.state.get("columns");    
    return prepareCells(rows, columns);
},

最后在html Blaze页面中有类似的内容:

{{#each row in matrixContents.rows}}
     {{#each row.cell}}
          {{> cellcontent}}
     {{/each}}
{{/each}}

每当反应变量发生变化时,辅助函数就会重新运行..但是“cellContent”模板的onCreated函数不是!例如,如果添加一行,则onCreated仅运行n次(其中n是当前列数),而函数“prepareCells”始终返回一个新对象。在onCreated内部,必须执行一些相关逻辑来初始化单元内容的正确反应变量。

Meteor使用什么模式决定何时创建新模板?我找到了一个解决方法,其中cellcontent的帮助程序(内部模板)使用currentData:

Template.cellcontent.helpers({
    getFoo(){
         let data = Template.currentData();
         ...logic with the "real" data inside the cellcontent
    }

因为依赖于reactiveDict的cellcontent的帮助者会发现意外的值,因为reactiveDict是在onCreated上启动的,并不总是运行,例如:

Template.cellcontent.helpers({
    getFoo(){
         let template = Template.instance();
         instance.state =....you get unexpected data here

    }

是否有关于此行为的参考?

1 个答案:

答案 0 :(得分:1)

为了重新运行您的onCreated函数,您需要a)添加一个autorun b)将其绑定到反应性源,以便该源触发自动运行,最后c)传递一些数据以触发自动运行。

鉴于上面的示例,该示例如下所示:

Template.cellcontent.onCreated(function cellContentOnCreated() {

  const instance = this;
  instance.state = new ReactiveDict(); // to save the processed data

  // a - autorun this instance on changing incoming data
  instance.autorun(function autorun() {

    // b - autobind to a reactive data source
    // because Template.currentData() is in a reactive context
    // autorun will automatically re-run if it changes
    const data = Template.currentData();
    const processedData = //... process your incoming data
    instance.state.set('processedData', processedData);
  });

});

Template.cellcontent.helpers({
  getFoo(){
    return Template.instance().state.get('processedData');
  }
});

为了实现c),您需要将一些数据传递到单元格内容模板中:

{{#each row in matrixContents.rows}}
     {{#each row.cell}}
          {{> cellcontent data=this}}
     {{/each}}
{{/each}}

请注意,this代表每个块中的当前元素,并且要求row.cell是单元格内容元素的数组。如果不是这种情况,则可以查看此结构并重新组织,以便将单元格内容数据传递到cellcontent模板。