Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ExtJS 5:访问组件中的绑定存储_Javascript_Extjs_Data Binding_Extjs5 - Fatal编程技术网

Javascript ExtJS 5:访问组件中的绑定存储

Javascript ExtJS 5:访问组件中的绑定存储,javascript,extjs,data-binding,extjs5,Javascript,Extjs,Data Binding,Extjs5,我很难理解如何访问组件(如组合框或网格)上的实际绑定存储实例。当您使用他们的getStore方法时,它似乎会返回一个不同的实例 在我的中,我有一个自定义网格类,在它的initComponent中,我想添加一个负载侦听器。不幸的是,加载侦听器从未被命中,但绑定存储的加载侦听器却被命中。您可以看到,在加载存储之前,侦听器已经设置好,所以这不是问题所在。initComponent中的存储实例似乎是内存存储,因此绑定存储的实例此时未同步到该组件 我知道我可以在绑定存储上有一个加载侦听器,但这是一个自定义

我很难理解如何访问组件(如组合框或网格)上的实际绑定存储实例。当您使用他们的getStore方法时,它似乎会返回一个不同的实例

在我的中,我有一个自定义网格类,在它的initComponent中,我想添加一个负载侦听器。不幸的是,加载侦听器从未被命中,但绑定存储的加载侦听器却被命中。您可以看到,在加载存储之前,侦听器已经设置好,所以这不是问题所在。initComponent中的存储实例似乎是内存存储,因此绑定存储的实例此时未同步到该组件

我知道我可以在绑定存储上有一个加载侦听器,但这是一个自定义网格类,对于任何自定义网格类,我都希望设置一个侦听器。。。所以我不想在我的代码中到处都这样做。。。我只想把它放在一个类中,因为它们都将执行相同的逻辑

有人能给我解释一下为什么我的自定义网格类的负载侦听器没有受到攻击,我能做些什么来修复这个问题?我能否以某种方式访问绑定存储实例

Ext.application({
  name: 'Fiddle',

  launch: function() {
    Ext.define('MyGrid', {
      extend: 'Ext.grid.Panel',
      xtype: 'myGrid',
      initComponent: function() {
        alert('initComponent')
        this.callParent();
        this.getStore().on('load', this.onLoad, this);
      },
      onLoad: function() {
        alert('grid store loaded');
      }
    });
    Ext.define('MyViewController', {
      extend: 'Ext.app.ViewController',
      alias: 'controller.myview',
      onLoadBoundStore: function() {
        alert('loaded bound');
      }
    })
    Ext.define('MyViewModel', {
      extend: 'Ext.app.ViewModel',
      alias: 'viewmodel.myview',
      stores: {
        myStore: {
          fields: ['name', 'value'],
          autoLoad: true,
          proxy: {
            type: 'ajax',
            url: 'data1.json',
            reader: {
              type: 'json'
            }
          },
          listeners: {
            load: 'onLoadBoundStore'
          }
        }
      }
    });
    Ext.define('MyView', {
      extend: 'Ext.form.Panel',
      renderTo: Ext.getBody(),
      controller: 'myview',
      viewModel: {
        type: 'myview'
      },
      items: [{
        title: 'blah',
        xtype: 'myGrid',
        reference: 'myComboBox',
        bind: {
          store: '{myStore}'
        },
        columns: [{
          text: 'Name',
          dataIndex: 'name'
        }, {
          text: 'Value',
          dataIndex: 'value'
        }]
      }]
    });
    Ext.create('MyView')
  }
});
有人能解释一下为什么我的自定义网格类的负载侦听器是 没有被击中,我能做些什么来解决这个问题

您最初没有向网格提供任何存储(顺便说一下,config选项是必需的)。因此,网格正在创建自己的空存储,编码如下:

该空存储区是连接您的
onLoad
侦听器的存储区。它不会被击中,因为商店从未加载

我可以用某种方式访问吗 绑定存储实例

Ext.application({
  name: 'Fiddle',

  launch: function() {
    Ext.define('MyGrid', {
      extend: 'Ext.grid.Panel',
      xtype: 'myGrid',
      initComponent: function() {
        alert('initComponent')
        this.callParent();
        this.getStore().on('load', this.onLoad, this);
      },
      onLoad: function() {
        alert('grid store loaded');
      }
    });
    Ext.define('MyViewController', {
      extend: 'Ext.app.ViewController',
      alias: 'controller.myview',
      onLoadBoundStore: function() {
        alert('loaded bound');
      }
    })
    Ext.define('MyViewModel', {
      extend: 'Ext.app.ViewModel',
      alias: 'viewmodel.myview',
      stores: {
        myStore: {
          fields: ['name', 'value'],
          autoLoad: true,
          proxy: {
            type: 'ajax',
            url: 'data1.json',
            reader: {
              type: 'json'
            }
          },
          listeners: {
            load: 'onLoadBoundStore'
          }
        }
      }
    });
    Ext.define('MyView', {
      extend: 'Ext.form.Panel',
      renderTo: Ext.getBody(),
      controller: 'myview',
      viewModel: {
        type: 'myview'
      },
      items: [{
        title: 'blah',
        xtype: 'myGrid',
        reference: 'myComboBox',
        bind: {
          store: '{myStore}'
        },
        columns: [{
          text: 'Name',
          dataIndex: 'name'
        }, {
          text: 'Value',
          dataIndex: 'value'
        }]
      }]
    });
    Ext.create('MyView')
  }
});
是的,使用这个:

this.lookupViewModel().getStore('myStore')
您可以将侦听器附加到绑定的存储区,而不是空的存储区,并查看差异。网格的空存储最终会被绑定的存储替换(这就是为什么您会在网格中看到数据的原因),但这是在执行
initComponent
之后发生的。您可以通过覆盖
setStore
方法跟踪将绑定存储设置到网格的时刻

我知道我可以在绑定存储上有一个加载侦听器,但这是一个 自定义网格类,对于任何自定义网格类,我都希望有一个 侦听器设置。。。所以我不想一辈子都这样 在我的代码中放置。。。我只想把它放在一节课上,因为他们都在上课 执行相同的逻辑


由于您使用的是MVVC,因此建议您坚持使用该模式,并保留仅声明视图方面的视图。侦听器应该在控制器中声明和处理(甚至不像示例中那样在viewmodels中)。否则,如果你继续坚持Ext JS 5之前的风格,并在视图中添加动态内容(即,在你的例子中的网格),那么使用MVVC是没有意义的。

这太令人难以置信了,我甚至不想将其作为一个答案发布,但我只是为了子孙后代的缘故。基于Drake的答案,我找到了如何使用网格类初始配置中传递的内容来获取我的存储。绑定带有大括号,这就是为什么我在它上面做了一个
replace
。就像我说的,这可能永远都不应该被使用,但它是一种东西

initComponent: function() {
  var store = this.lookupViewModel().getStore(this.config.bind.store.replace(/[{}]/g, ''));
  store.on('load', this.onLoad, this);
  this.callParent();
},

只需在混合中添加一个选项,您就可以在网格上侦听事件,因为绑定存储完成后将触发该事件。。。因此,类似这样的方法会起作用:

Ext.application({
  name: 'Fiddle',

  launch: function() {
    Ext.define('MyGrid', {
      extend: 'Ext.grid.Panel',
      xtype: 'myGrid',
      initComponent: function() {
        alert('initComponent')
        this.on('reconfigure', this.onReconfigureGrid, this);
        this.callParent();
      },
      onReconfigureGrid: function(grid, store, columns, oldStore, oldColumns, eOpts) {
        store.on('load', this.onLoad, this);
      },
      onLoad: function() {
        alert('grid store loaded');
      }
    });
    Ext.define('MyViewController', {
      extend: 'Ext.app.ViewController',
      alias: 'controller.myview',
      onLoadBoundStore: function() {
        alert('loaded bound');
      }
    })
    Ext.define('MyViewModel', {
      extend: 'Ext.app.ViewModel',
      alias: 'viewmodel.myview',
      stores: {
        myStore: {
          fields: ['name', 'value'],
          autoLoad: true,
          proxy: {
            type: 'ajax',
            url: 'data1.json',
            reader: {
              type: 'json'
            }
          },
          listeners: {
            load: 'onLoadBoundStore'
          }
        }
      }
    });
    Ext.define('MyView', {
      extend: 'Ext.form.Panel',
      renderTo: Ext.getBody(),
      controller: 'myview',
      viewModel: {
        type: 'myview'
      },
      items: [{
        title: 'blah',
        xtype: 'myGrid',
        reference: 'myComboBox',
        bind: {
          store: '{myStore}'
        },
        columns: [{
          text: 'Name',
          dataIndex: 'name'
        }, {
          text: 'Value',
          dataIndex: 'value'
        }]
      }]
    });
    Ext.create('MyView');
  }
});

哇,非常感谢!你又给了我几个后续问题
store config选项是必需的
对,但我正在绑定一个存储,所以即使绑定一个存储,您是否真的要声明一个存储?这似乎是多余的。
侦听器应该在控制器中声明和处理(甚至不像您的示例中那样在viewmodels中)。
因此,按照这种逻辑,您是说我也不应该在视图中声明侦听器?我想这会给控制器增加太多的膨胀。。。然后我必须查找所有引用并添加侦听器。。。考虑到我有一种方便的添加侦听器的方法,这似乎有点不必要。
这个.lookupViewModel()
是一个非常有趣的知识。。。考虑到
this.getViewModel()
返回null。看起来后者是当前级别viewModel的一个方便的获取工具,然后lookupViewModel将一直运行,直到找到一个,这将是继承的。同时重新绑定存储并提供存储配置-是的,这是多余的,但如果不执行后一个操作,则将不必要地创建空存储。我不确定这里推荐的做法是什么。您在哪里看到商店可以通过viewmodel绑定?也许答案就在那里。。。我认为这在控制器中增加了太多的膨胀,那么问问自己,如果在视图中添加侦听器很方便的话,为什么要使用控制器呢?如果让控制员参与进来,我会把他们应该做的所有工作都委派给他们。这是所有的品味问题,直到它花费你美元的那一天。只是想:你可以把
This.store=This.lookupViewModel().getStore('myStore')
this.callParent()之前
。这既可以防止创建空存储,又可以使示例按预期工作。