嵌套 dom-repeat 中数组映射的更改通知

Change notification for map of arrays in nested dom-repeat

我正在尝试向数组映射中添加一些内容,但值绑定没有接受更改:-(

我有这样的东西:

       properties: {
            deals: {
                type: Object,
                notify: true,
                value: function () {
                    return {
                        items: {
                            "MONDAY": [],
                            "TUESDAY": [],
                            "WEDNESDAY": [],
                            "THURSDAY": [],
                            "FRIDAY": [],
                            "SATURDAY": [],
                            "SUNDAY": []
                        }
                    }
                },
            },
            weekDays: {
                type: Array,
                value: function () {
                    return [
                        {"text": "Montag", "key": "MONDAY"},
                        {"text": "Dienstag", "key": "TUESDAY"},
                        {"text": "Mittwoch", "key": "WEDNESDAY"},
                        {"text": "Donnerstag", "key": "THURSDAY"},
                        {"text": "Freitag", "key": "FRIDAY"},
                        {"text": "Samstag", "key": "SATURDAY"},
                        {"text": "Sonntag", "key": "SUNDAY"}
                    ]
                },
            },
        },

然后我嵌套了 dom-repeat 来渲染元素。当我使用像

这样的函数时这有效
        _itemsForDay: function (day,map) {
            const data = map[day.key];
             return data;
        }

但是当我添加元素时它没有被重新绘制并且我尝试了很多 notifyPath 变体,但它没有呈现新元素:-(

这是我试过合二为一的:

  add: function (e) {
            day = e.model.day.key;
            this.push("deals.items." + day,
                {
                    description: "Bla",
                    price1: "23,45€",
                    price2: "43,21€",
                    imageId: 1
                }
            );
            this.notifyPath("weekDays");
            this.notifyPath("weekDays.*");
            this.notifyPath("weekDays.splice");
            this.notifyPath("deals.items.*");
            this.notifyPath("deals.items.*");
            this.notifyPath("deals.items.splice");
            this.notifyPath("deals.items."+day);
            this.notifyPath("deals.items."+day+".*");
            this.notifyPath("deals.items."+day+".splice");
            this.notifyPath("weekDays.*");
            console.log("Length: "+this.deals.items[day].length)
        },

如何确保地图键的内容被重新渲染(也可以重新渲染整个地图,我不关心)。

模板如下所示:

       <tr>
            <template is="dom-repeat" items="{{weekDays}}" as="day" >
                <td>
                    <template is="dom-repeat" items="{{_itemsForDay(day,deals.items)}}" >
                        <div>
                            DESC: [[item.description]]
                            IMG: [[item.imageId]]
                            [[deals.price1Label]]: [[item.price1]]
                            [[deals.price2Label]]: [[item.price2]]
                        </div>
                    </template>
                    <paper-button on-click="add" data-day="[[day.key]]">
                        +
                    </paper-button>
                </td>
            </template>
        </tr>

有趣的是,当我删除外循环并使用固定工作日时,它起作用了:

              <td>
                    <template is="dom-repeat" items="{{deals.items.TUESDAY}}" >
                        <div>
                            DESC: [[item.description]]
                            IMG: [[item.imageId]]
                            [[deals.price1Label]]: [[item.price1]]
                            [[deals.price2Label]]: [[item.price2]]
                        </div>
                    </template>
                    <paper-button on-click="add" data-day="TUESDAY">
                        +
                    </paper-button>
                </td>

这会拾取更改并呈现新项目,但我必须多次复制内部部分,这远非理想。

Slack 频道中的 ZeeWolf 有一个不错的想法,它奏效了:

新建 属性:

                dayLists: {
                    type: Array,
                    computed: '_computeDayLists(deals.items.*)'
                }

添加计算方法:

        _computeDayLists: function() {
            return this.weekDays.map(day => {
                const dayKey = day.key;
                const items = this.deals.items[dayKey];
                console.log("Found for "+dayKey+" #"+items.length+" items");
                return {
                    key: dayKey,
                    items: items
                }
            });
        },

更新模板:

           <template is="dom-repeat" items="{{dayLists}}" >
                <td>
                    <template is="dom-repeat" items="{{item.items}}" mutable-data>
                        <div>
                            DESC: [[item.description]]
                            IMG: [[item.imageId]]
                            [[deals.price1Label]]: [[item.price1]]
                            [[deals.price2Label]]: [[item.price2]]
                        </div>
                    </template>
                    <paper-button on-click="add">
                        +
                    </paper-button>
                </td>
            </template>
        add: function (e) {
            const day = e.model.item.key;
            this.push("deals.items." + day,
                {
                    description: "Bla",
                    price1: "23,45€",
                    price2: "43,21€",
                    imageId: 1,
                    new: true
                }
            );
            console.log("Length: " + this.deals.items[day].length)
        },

说明

内部循环不知何故没有接受更改,所以这种方法使用计算列表,它依赖于地图项内容(.* 启用此功能)。当其中的某些内容发生变化时,这会重新绘制列表。 重要的是 mutable-data 没有它,那是行不通的!

并确保您拥有最新版本的聚合物。我有一个旧版本,由于错误配置的 bower maven 步骤而没有更新,并且在我更新依赖项之前它没有工作。

我也遇到过这个问题,grrr!试试这个。

进行新的计算属性

static get properties() {
    return {
        ...
        'dayDeals': {
            type: Array,
            computed: 'computeDayDeals(deals.items)'
        }
    }
}

computeDayDeals(deals.items) {
    return Object.keys(deals.items).map(x => { day: x, deals: deals.items[x].deals });
}

_itemsForDay(day,deals.items)改成_itemsForDay(day, dayDeals.*)然后像这样:

_itemsForDay(day, dayDeals) {
    return !!dayDeals.base ? dayDeals.base.find(x => x.day == day.key).deals : [];
}