Мутирующий массив в массиве (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);