Метеор: проблема с реактивностью в цикле #each

К сожалению, мне не разрешено публиковать изображения, поэтому немного сложнее показать проблему. Поэтому я опишу это здесь. В моем последнем Meteor на экране у меня есть счет с позициями. Позиции и все работают отлично и отображаются так, как ожидалось. Что я хотел сделать, так это «вломиться» в цикл #each-loop после того, как 4 элемента строки будут напечатаны на экране, а затем сделать что-то еще (рассчитать и распечатать промежуточные итоги). Я не могу заставить это работать, так как var сеанса, который я создал для этого, похоже, не меняется реактивно в каждой строке. Вместо этого он, кажется, содержит последнее значение из полного цикла #each.

Обратите внимание, что там есть переменная listindex, которая идеально реактивно наращивает от 1 до 2, 3 и 4 для каждой строки, которая находится в цикле #each. Итак, переменная listindex действительно работает реактивно в цикле #each.

В то же время я ввожу туда сеансовую переменную, которая должна быть «истинной» в позиции номер 4 и «ложной» во всех остальных случаях. При значении «true» здесь должно быть напечатано «onderbreking». Однако переменная сеанса всегда дает "true" и (из-за этого) всегда печатает "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;

Наконец, это html, задействованный в layout6.html:

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

И, конечно же, есть оператор {{/each}}, но между ними много кода, который не очень важен для этой проблемы, поэтому я не помещал его здесь.

Я надеюсь, что я включил все, если нет, вы, ребята, несомненно, скажете мне.

Вопрос: что я делаю не так, чтобы сессионный var не менялся реактивно внутри цикла #each?


person user2207415    schedule 05.08.2014    source источник


Ответы (1)


Это не совсем правильный способ использования переменных сеанса. Переменные сеанса предназначены для глобального состояния приложения, а не для хранения промежуточных значений посредством одного вычисления. Общее правило заключается в том, что шаблоны и помощники шаблонов не должны иметь побочных эффектов (например, установка переменных сеанса).

Я бы выбрал другой подход. Определите помощника:

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.

person user3374348    schedule 05.08.2014
comment
Большое спасибо за Ваш ответ ! Я благодарен за любую помощь. Но мне трудно понять, что именно вы делаете в своих функциях. Если возможно, не могли бы вы подробнее рассказать о том, что именно происходит в этих функциях? - person user2207415; 05.08.2014
comment
Я реализовал ваш код как есть, и теперь вообще не отображаются элементы строки. Очевидно, вы ожидаете, что я изменю что-то в своем коде помимо того, что вы указали выше, чего я не уловил :-) извините за это .... вы можете помочь? - person user2207415; 05.08.2014
comment
Кроме того, я только что заметил, что в {{#each listItemsWithIndex}}, похоже, есть опечатка, вероятно, должно быть: {{#each lineItemsWithIndex}} ? - person user2207415; 05.08.2014
comment
Я не уверен, что такое factuur6, я догадался, что это поле, но если это был помощник, вам придется вызывать его вместо этого, см. Мое редактирование. - person user3374348; 05.08.2014
comment
Factuur6 действительно является помощником, определяемым следующим образом: Template.layout6.factuur6 = function(){ return Factuurlijst.findOne({_id:Session.get('factuurid')}); } - person user2207415; 05.08.2014
comment
Оно работает. Это действительно здорово. Теперь, с добавленным объяснением, я могу пойти и изучить то, что вы здесь создали. Большое спасибо за то, что помогли мне и приложили дополнительные усилия, чтобы объяснить это мне. Я очень ценю это !! - person user2207415; 05.08.2014