商店更新后 ExtJS 网格不刷新

ExtJS Grid not refreshing after store update

我有一个网格和一个商店。存储中填充了一些数据 - country - 而其余的是空的。一旦我收到更多输入,我就会用这些输入填满商店。

假设我在初始加载后商店中只有 1 个国家/地区。

商店:

feedTheGrid = new Ext.data.JsonStore({
    autoDestroy : true,
    autoSave : false,
    autoLoad : true,
    idProperty: 'country',
    root: 'root',
    totalProperty : 'totalcount',
    fields : ['country', 'towns'],
    proxy : new Ext.data.HttpProxy(new Ext.data.Connection({
        url : "country/searchCountries.action",
        method : 'POST',
        timeout : 300000
    }))
});

于是用户输入城镇。我使用 push():

在数组 towns 中保存了一个城镇
listeners: {
    'change': function() {
        if (feedTheGrid.getAt(0).towns === undefined) {
            feedTheGrid.getAt(0).towns = [];
        }
        feedTheGrid.getAt(0).towns.push(this.getValue());
        gridMonster.getView().refresh();
    }
}

我希望每次放入新城镇时更新网格。

这是我用于 gridMonster:

的列模型的一部分
{ header: "Town 1", width: 150, dataIndex: 'towns', 
  renderer: function(val) {
      if (val[0] != undefined) {
          return val[0];
      }
  }, sortable: true},
{ header: "Town 2", width: 150, dataIndex: 'towns',
  renderer: function(val) {
      if (val[1] != undefined) {
          return val[1];
      }
  }, sortable: true},  
{ header: "Town 3", width: 150, dataIndex: 'towns',
  renderer: function(val) {
      if (val[2] != undefined) {
          return val[2];
      }
  }, sortable: true}

问题是将城镇放入网格后永远不会刷新。

到目前为止我注意到的一些事情:

当我查看 Firebug 时,商店会更新为新值。此外,渲染器中给出的 val 似乎始终为空字符串,即使在我将新值推入数组并刷新网格视图之后也是如此。

我正在使用 ExtJS 3.3.1

我知道它很旧,所以我愿意接受适用于 4.0+ 的解决方案,我可以尝试将它应用到 3.3.1。

编辑:发现问题

非常微妙的问题,花了几个小时试图找出问题所在才发现我找错了地方。问题出在这一行:

feedTheGrid.getAt(0).towns.push(this.getValue());

此行实际上创建了一个新字段 towns 作为您使用 getAt(0) 获得的记录的一部分。使用 firebug 查看 getAt(0).towns[0] 是否实际填充 returns 您推送的值具有误导性。

ExtJS 不知道这个新字段,也不应该。

这一行应该是:

feedTheGrid.getAt(0).data.towns.push(this.getValue());

诀窍是指向正确的位置:.data。 Javascript/ExtJS 允许您在没有任何警告的情况下添加新字段,因为从技术上讲您没有做错任何事情。从逻辑上讲,它会创建一个什么都不做的新字段。

@Lorenz Meyer 我能够在指向列模型中的 towns 数组时使用渲染器显示数组的元素。

对于 ExtJs 中什么是商店和网格存在一个重大误解。

两者都只是表格数据的表示。 store 是 table 在内存中的表示,以便快速访问记录过滤和更多功能。 grid 是 table 在浏览器中的视觉表示 window.

这样的 table 可能看起来像 :

Id | Country | City
-------------------
1  | US      | NYC
2  | France  | Macon
3  | US      | Macon

首先,在 table 行中,您只能有一个城市。在 tables 中,您不能在单个字段中包含数组。如果您有多个城市,这就是 的用途。

那么,你的idProperty不能是国家。如果是的话,这将意味着国家是独一无二的。显然,他们不是。一个国家可以有多个城市。 (cities 也不能是 idProperty,因为存在多个相同的城市)。

现在您肯定开始明白,feedTheGrid.getAt(0).towns.push(this.getValue()); 毫无意义。 towns 列不能是数组。您使用 feedTheGrid.add({country: 'US', towns: 'LA'}).
插入一个新行 towns 列最多可以是逗号分隔值,在这种情况下,您可以使用

更新商店
var record = feedTheGrid.getAt(0),
currentTowns = record.get('towns');
record.set('towns', currentTowns + ', ' + value)

记录的方法 set 发挥了所有作用:它将更新事件传递给网格以便重新呈现它。您的 push 除了错误之外不会触发更新视图所需的事件。

关于网格:网格的列应该是:

{ header: "Id", width: 150, dataIndex: 'id', sortable: true},
{ header: "Country", width: 150, dataIndex: 'country', sortable: true},  
{ header: "Town(s)", width: 150, dataIndex: 'towns', sortable: true}

备注:

  • 那个 listeners: 对我来说真的很奇怪,但也许只是因为缺少大局。
  • feedTheGrid 是一个奇怪的商店名称。商店不提供数据。它数据。
  • 渲染器始终必须 return 一个值,否则单元格将保持空白。因此您的渲染器无法工作。

在您的渲染器中,val 不能是数组。这是一个简单的变量。这就是为什么您的网格不刷新的原因。

非常微妙的问题,花了几个小时试图找出问题所在才发现我找错了地方。问题出在这一行:

feedTheGrid.getAt(0).towns.push(this.getValue());

这一行实际上创建了一个新的字段 towns 作为您使用 getAt(0) 获得的记录的一部分。使用 firebug 查看 getAt(0).towns[0] 是否实际填充 returns 您推送的值具有误导性。

ExtJS 不知道这个新字段,也不应该。

这一行应该是:

feedTheGrid.getAt(0).data.towns.push(this.getValue());

诀窍是指向正确的位置:.data。 Javascript/ExtJS 允许您在没有任何警告的情况下添加新字段,因为从技术上讲您没有做错任何事情。从逻辑上讲,它会创建一个什么都不做的新字段。

@Lorenz Meyer 我能够在指向列模型中的 towns 数组时使用渲染器显示数组的元素。