首页 > 解决方案 > 将项目添加到子数组时,聚合物嵌套的 dom-repeat 模板不会更新

问题描述

语境

我正在制作一个显示项目列表的页面。该页面列出了从最新到最旧的项目,并首先按年分类,然后按月分类。它看起来类似于以下示例:

2019

行进

二月

2018

十月

可能

HTML 的简化版本是:

<template is="dom-repeat" items="{{years}}" as="year">
    <span>[[year.name]]</span>
    <div id="same-year-items>
        <template is="dom-repeat" items="{{year.months}}" as="month">
            <span>[[month.name]]</span>
            <div id="same-month-items">
                <template is="dom-repeat" items="{{month.items}}" as="item">
                    <custom-list-item item="{{item}}"></custom-list-item>
                </template>
            </div>
        </template>
    </div>
</template>

在 Javascript 文件中,我定义了一个years数组属性。in 中的每一年都years包含一个months数组,in 中的每个月都months包含一个items数组(参见 dom-repeat 元素)。我在数据库中查询一些列表项,遍历每个项,然后将其添加到相应的月份数组中。

问题

此页面仅加载前 n 项。我想在底部有一个“加载更多”按钮,用于加载接下来的 n 个项目。(是的,我知道。无限滚动可能会更好——稍后会出现。即使我要使用无限滚动,我仍然会遇到我要描述的问题。)

当我加载更多项目时,页面不会更新以显示新项目。我知道 Polymer 对绑定数据的方式非常讲究,尤其是在涉及子属性时。这是 Javascript 的简化版本,用于将新项目设置为数组:

setItems: function(newItems) {
  var tempYearsArray = [];
  for (var i = 0, i < this.years.length; i++) {
    tempYearsArray.push(this.years[i]);
  }
  
  this.set('years', []);
  
  for (var j = 0; j < newItems.length; j++) {
    var item = newItems[j];
    this.setMonthAndYear(item, tempYearsArray);
  }
  
  this.set('years', tempYearsArray);
}

setMonthAndYear: function(item, tempYearsArray) {
  var itemDate = new Date(item.lastModified);
  var currentYear = itemDate.getFullYear();
  var monthIndex = itemDate.getMonth();
  var monthName = this.monthNames[monthIndex];
  var newYear = true;
  var newMonth = true;
  for (var i = 0; i < tempYearsArray.length; i++) {
    var year = tempYearsArray[i];
    if (currentYear === year.name) {
      newYear = false;
      for (j = 0, j < year.months.length; j++) {
        var month = ref[j];
        if (monthName === month.name) {
          month.items.push(item);
          newMonth = false;
          break;
        }
      }
      if (newMonth) {
        var month = {
          items: [item],
          name: monthName
        };
        year.months.push(month);
      }
      break;
    }
  }
  if (newYear) {
    var month = {
      items: [item],
      name: monthName
    };
    year = {
      name: currentYear,
      months: [month]
    };
    return tempYearsArray.push(year);
  }
}

我可以看到years有新项目,但页面仍然没有呈现它们。我读过其他有类似问题的帖子,这是我想到this.set('years', [])临时数组的地方。我也尝试过像this.notifyPath('year.months', year.months.slice())and之类的东西this.notifyPath('month.items', month.items.slice())。我不确定为什么这会起作用,但我在这个 Github 问题帖子中看到了建议。

此外,如果您有比包含项目数组的月份数组的年数组更好的建议,那就更好了。

标签: polymer

解决方案


我让它工作了。它不像 Polymer 那样优雅或惯用,但它有效,所以我在这里分享它。

我做了一个items存储所有物品的财产。然后,当我加载一批新项目时,我将新项目推送到现有项目数组并years再次重建整个数组。


推荐阅读