【问题标题】:Meteor: issue with reactivity in the #each loopMeteor:#each 循环中的反应性问题
【发布时间】:2014-09-27 20:33:26
【问题描述】:

很遗憾,我不被允许发布图片,这使得展示手头的问题变得有点困难。所以我会在这里描述它。 在屏幕显示的最后 Meteor 中,我有一张包含行项目的发票。订单项和所有项目都完美运行并按预期显示。 我想做的是在屏幕上打印 4 个行项目后在#each-loop 中“闯入”,然后做其他事情(计算和打印小计)。我无法让它工作,因为我为此创建的会话变量似乎并没有在每个订单项上发生反应性变化。相反,它似乎保留了完整 #each 循环中的最后一个值。

请注意,其中有一个 listindex 变量,它在#each 循环中的每个行项目上完美地从 1 到 2,3 和 4 构建。因此,listindex 变量确实在#each 循环中反应性地工作。

同时,我在其中引入了一个会话变量,在第 4 行项目上应该是“真”,在所有其他情况下应该是“假”。在“真”上,它应该在那里打印“onderbreking”。但是,会话变量 always 给出“true”并且(因此)always 打印“onderbreking”。这当然不是我想要的工作方式。

我不明白为什么 listindex 有效,而 session var 无效?

这是我的 javascript。该模板名为“layout6.html”:

  Template.layout6.helpers({
        // Bereken de index in de #each loop
        listIndex: function() {
          currentIndex += 1;
          if(currentIndex == 4) {
            Session.set('sessionPageBreak1', true);
          }
          if(currentIndex != 4) {
            Session.set('sessionPageBreak1', false);
          }
        return currentIndex;
        },            
  });    

 Template.layout6.SessionPageBreak1 = function() {
            // Voeg de waarde van de sessie variabele toe aan de template
            var data = Session.get('sessionPageBreak1');
            return data;
 };

会话变量最初设置在这里:

  // Session var for layoutcounter
  Session.setDefault('sessionPageBreak1', false);
  Session.setDefault('sessionPageBreak2', false); 
  Session.setDefault('sessionPageBreak3', false);  
  var currentIndex = 0.0;

最后是layout6.html上涉及的html:

{{#each factuur6.lineItems}}
  {{listIndex}}
  {{SessionPageBreak1}}
{{#if SessionPageBreak1}}
<div><p>onderbreking</p></div>
{{/if}}

当然,还有一个 {{/each}} 语句,但是中间有很多与这个问题不太相关的代码,所以我没有放在这里。

我希望我包括了所有内容,如果没有,你们肯定会告诉我的。

问题是:我做错了什么,所以会话变量在#each 循环中没有反应性地改变?

【问题讨论】:

    标签: meteor spacebars


    【解决方案1】:

    这并不是使用 Session 变量的正确方法。会话变量用于全局应用程序状态,而不是用于通过单个计算存储中间值。一般规则是模板和模板助手不应该有副作用(比如设置会话变量)。

    我会采取不同的方法。定义一个助手:

    lineItemsWithIndex: function () {
      return _.map(this.factuur6.lineItems, function (item, index) {
        var newItem = _.clone(item);
        newItem.index = index;
        return newItem;
      });
    }
    

    此函数返回this.factuur6.lineItems 的副本,但每个对象都添加了index 属性。例如,如果lineItems 的列表是[{name: "foo"}, {name: "bar"}, {name: "baz"}],我们返回[{name: "foo", index: 0}, {name: "bar", index: 1}, {name: "baz", index: 2}]。原名单不变。如果factuur6 是帮助器而不是字段,则改用_.map(Template.layout6.factuur6().lineItems ...

    然后在您的模板中对其进行迭代:

    {{#each lineItemsWithIndex}}
      {{index}}
      {{pageBreak1}}
      {{#if pageBreak1}}
        <div><p>onderbreking</p></div>
      {{/if}}
    {{/each}}
    

    其中pageBreak1 是一个助手function () {return this.index == 3;}(3 而不是 4,因为这些索引是从 0 开始的)。由于我们为每个对象添加了索引,现在可以在帮助程序中访问它。

    这假设您的订单项还没有名为 index 的字段。

    【讨论】:

    • 非常感谢您的回复!我很感激任何帮助。但是我无法理解您在函数中到底在做什么。如果可能的话,您能否详细说明一下这些函数中到底发生了什么?
    • 我按原样实现了您的代码,现在根本没有显示任何 lineItems。显然,您希望我在我的代码中调整超出您上述内容的内容,我没有接受 :-) 对此感到抱歉....您能帮忙吗?
    • 另外,我刚刚注意到,{{#each listItemsWithIndex}} 似乎有错字,应该是:{{#each lineItemsWithIndex}}?
    • 我不确定factuur6 是什么,我猜它是一个字段,但如果它是一个帮助器而不是你必须调用它,请参阅我的编辑。
    • Factuur6 确实是一个助手,定义如下: Template.layout6.factuur6 = function(){ return Factuurlijst.findOne({_id:Session.get('factuurid')}); }
    猜你喜欢
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    • 2019-08-29
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多