Мутирующий массив в массиве (Polymer iron-list)

У меня в настоящее время есть железный список в другом железном списке. Родительские данные поступают из элемента firebase-query, а дочерние данные вычисляются из каждого родительского элемента. Структура и код БД выглядит примерно так:

DB: [
     category1: [
                 itemId1: {
                           price: 10,
                           title: "title" 
                          }
                ]
    ]



<iron-list id="categoryList" items="{{categories}}" multi-selection as="category">
        <template>
            <div class="category-holder">
                <iron-list id="{{category.$key}}" items="{{_removeExtraIndex(category)}}" as="item" selection-enabled multi-selection selected-items="{{selectedItems}}" grid>
                    <template>
                        <div class$="{{_computeItemClass(selected)}}">
                            <p>[[item.title]]</p>
                            <p>[[item.price]]</p>
                        </div>
                    </template>
                </iron-list>
            </div>
        </template>
    </iron-list>

После выбора любого количества предметов пользователь может нажать на потрясающий, чтобы пакетно редактировать цену. Здесь у меня проблемы. Я не могу понять, как получить доступ к правильному дочернему железному списку, чтобы вызвать list.set... В настоящее время я пытаюсь использовать следующий очень неприятный метод:

var categories = this.$.categoryList;
var categoryItems = categories.items;

(this.selectedItems).forEach(function(item) {
    var index = item.itemId;
    categoryItems.forEach(function(itemList, categoryIndex) {
    if (itemList[index]) {
         categories.set('item.' + categoryIndex + '.price', 10);
         }
    }, this);
}, this);

Я перебираю выбранные элементы, чтобы извлечь индекс элемента, а затем перебираю родительские данные списка железа (categoryItems), чтобы проверить, существует ли данный элемент в этом подмножестве данных. Если так, то я использую индекс категории и пытаюсь вызвать set из родительского списка железа, используя заданный путь для доступа к фактическому элементу, который я хочу редактировать. Как и следовало ожидать, это не удается. Надеюсь, я прояснил себя достаточно, любая помощь будет оценена!

РЕДАКТИРОВАНИЕ № 1:

После долгих экспериментов я наконец понял, как правильно изменить дочерний список железа:

(this.selectedItems).forEach(function(item) {
                var list = this.$.categoryList.querySelector('#' + item.category);
                var index = list.items.indexOf(item);
                list.set(["items", index, "price"], 30);                   
            }, this);

Несколько вещей стоит отметить. Я использую querySelector вместо рекомендованного this.$$(селектор), потому что я продолжаю сталкиваться с ошибкой "DNE функции". Но теперь у меня есть другая проблема... после вызова функции значение обновляется правильно, но я получаю следующую ошибку:

Uncaught TypeError: inst.dispatchEvent is not a function

Вот изображение полного сообщения об ошибке:

Я вижу свет, надеюсь, кто-то может мне помочь!

1 ответ

Хорошо, я сделаю снимок. Я думаю, что происходит следующее, и я предполагаю, что это основано на том, как работает dom-repeat:

  var categories = this.$.categoryList;
  var categoryItems = categories.items;

Вы берете переменную, на которой основан список железа, но установка одного массива на другой просто создает ссылку в javascript. Как только вы обновляете categoryItems, вы также обновляете это.$. CategoryList.items. Когда вы позже установите новое значение, iron-list выполнит грязную проверку и сравнит все подвойства, и поскольку они равны (потому что... ссылка), iron-list не будет обновлять dom.

Что вы должны сделать, это убедиться, что это абсолютно новая копия, и способ сделать это - использовать JSON.parse (JSON.stringify (myArray)).

Кроме того, в вашем коде есть один существенный недостаток: вы используете querySelector для выбора элемента, а затем манипулируете им. Что вы должны сделать, это использовать this.categories и только эту переменную.

Итак, ваш метод должен выглядеть примерно так:

  // Get a freshly new array to manipulate
  var category = JSON.parse(JSON.stringify(this.categories);

  // Loop through it
  category.forEach(category) {
    // update your categoryList variable
  }

  // Update the iron list by notifying Polymer that categories has changed.
  this.set('categories', category);
Другие вопросы по тегам