Polymer - уведомить, что объект.property изменился в массиве для DOM - PullRequest
0 голосов
/ 07 декабря 2018

В Polymer 1. * у меня есть повтор.Объект obj.property не обновляется в DOM, когда я изменяю массив itemsCollection.

Я пытался 'this.notifyPath (itemCollection.${i}.value)' после 'this.set (itemCollection.${i}.value ,isting.value);'но это не обновлялось в DOM.

Должен ли я использовать вместо этого this.notifySplices?И если да, как бы я использовал его после this.set( itemCollection. $ {I} .value , existing.value);?

  _populateAlerts: function(existingValues) {
    this.itemCollection.forEach((question, i)=> {
      const existing =
        existingValues.find(value => value.name === question.name);

      this.set(`itemCollection.${i}.picklist_value_id`,
        existing.picklist_value_id);
      this.set(`itemCollection.${i}.value`, existing.value);
    });
  },

1 Ответ

0 голосов
/ 08 декабря 2018

this.notifyPath никогда не требуется, если вы используете this.set, и, вероятно, его следует использовать, только если другая инфраструктура устанавливает переменную.


Это странный код, с кубическим циклом и установкой подвойств вitemCollection, при прохождении через указанный массив, с помощью методов Polymer.

В любом случае, мне интересно, есть ли проблема со ссылками на массив.Где existingValues = itemCollection, поэтому каждый раз, когда existingValues изменяется, itemCollection также изменяется, но таким образом, что DOM не обновляется.Это означает, что itemCollection пытается установить себе уже существующее значение при установке через this.set, следовательно, не обновляя DOM посредством грязной проверки .

Простое решение может бытьпросто установите itemCollection с самой копией.

_populateAlerts: function(existingValues) {
  this.itemCollection.forEach((question, i)=> {
    const existing =
      existingValues.find(value => value.name === question.name);

    this.set(`itemCollection.${i}.picklist_value_id`,
      existing.picklist_value_id);
    this.set(`itemCollection.${i}.value`, existing.value);
  });

  this.set('itemCollection', JSON.parse( JSON.stringify(this.itemCollection) );

  // Alternatively
  // const tempArr = JSON.parse( JSON.stringify(this.itemCollection) );
  // this.set('itemCollection, []); // override dirty checking, as stated in the documentation
  // this.set('itemCollection', tempArr);
},

Другим решением может быть создание нового массива existingValues, нарушающего "цепочку ссылок", поэтому existingValues! = itemCollection.То есть, если проблема связана с ссылками.

_populateAlerts: function(existingValues) {
  const copiedExistingValues = JSON.parse( JSON.stringify(existingValues) );

  this.itemCollection.forEach((question, i)=> {
    const existing =
      copiedExistingValues.find(value => value.name === question.name);

    this.set(`itemCollection.${i}.picklist_value_id`,
      existing.picklist_value_id);
    this.set(`itemCollection.${i}.value`, existing.value);
  });
},

Однако, если вас интересует только первое вхождение, я бы создал объект существующие Arrays, чтобы избежать кубического зацикливания, а также разорвать цепочку ссылок..

_populateAlerts: function(existingValues) {
  const existingValuesObj = this._createObjectFrom(existingValues, 'name');

  this.itemCollection.forEach((question, i)=> {
    this.set(`itemCollection.${i}.picklist_value_id`,
      existingValuesObj[question.name].picklist_value_id);
    this.set(`itemCollection.${i}.value`, existingValuesObj[question.name].value);
  });
},

_createObjectFrom: function (arr, property, overwritePreviousObj) {
  var obj = {};
  var propertyName = '';

  for (var i = 0; i < arr.length; i++) {
     propertyName = arr[i][property];

     if (overwritePreviousObj) {
       obj[propertyName] = arr[i];
     } else if (!obj.hasOwnProperty(propertyName) {
       obj[propertyName] = arr[i];
     }
  }

  return obj;
},
...