ExtJS 5:访问组件中的绑定存储
ExtJS 5: Accessing bound store in component
我真的很难理解如何访问组件上的实际绑定存储实例,例如 ComboBox 或 Grid。看起来,当您使用他们的 getStore 方法时,它 returns 是一个不同的实例。
在我的 example 中,我有一个自定义网格 class,在它的 initComponent 中,我想添加一个加载侦听器。不幸的是,加载监听器永远不会被命中,但绑定存储的加载监听器会。您可以看到监听器是在加载商店之前设置的,所以这不是问题。看起来initComponent中的store实例是一个内存存储,所以此时绑定的store实例没有同步到组件。
我知道我可以在绑定存储上有一个加载监听器,但这是一个自定义网格 class,对于任何自定义网格 class,我希望设置一个监听器...所以我不想在我的代码中到处都这样做...我只想在一个 class 中执行此操作,因为它们都将执行相同的逻辑。
有人可以向我解释为什么我的自定义网格 class 的加载侦听器没有受到影响,我该怎么做才能解决这个问题?我能以某种方式访问绑定的商店实例吗?
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')
}
});
Can someone explain to me why my custom grid class's load listener is
not getting hit, and what can I do to fix this?
您最初没有向您的网格提供任何商店(store
config option is required by the way). Hence the grid is creating its own, empty store as coded here:
store = me.store = Ext.data.StoreManager.lookup(me.store || 'ext-empty-store');
那个空的商店是让您的 onLoad
听众附加的商店。它没有被击中,因为商店从未加载过。
Can I somehow access
the bound store instance?
是的,使用这个:
this.lookupViewModel().getStore('myStore')
您可以将您的侦听器附加到绑定存储而不是空存储,看看有什么不同。网格的空存储最终会被绑定的存储替换(毕竟这就是您在网格中看到数据的原因),但这发生在 initComponent
执行后。您可以通过覆盖 setStore
方法来跟踪将绑定存储设置到网格的时刻。
I know I can have a load listener on the bound store, but this is a
custom grid class, and for any custom grid class, I want there to be a
listener set up... so I don't want to have to do this all over the
place in my code... I just want it in one class, as they're all going
to have the same logic carried out.
由于您使用的是 MVVC,因此建议坚持该模式并保持视图仅声明视图方面。监听器应该在控制器中声明和处理(甚至不像你的例子那样在视图模型中)。否则,如果您继续坚持 Ext JS 5 之前的样式并将动态内容放入视图(即您的情况下的网格),则使用 MVVC 毫无意义。
这太骇人听闻了,我什至不想 post 将它作为答案,但为了 post 诚实起见,我将这样做。基于 Drake 的回答,我想出了如何使用在我的网格 class 的初始配置中传递的内容来获取我的商店。绑定与大括号一起出现,所以这就是我在其上执行 replace
的原因。就像我说的,这可能永远不应该使用,但它确实有用。
initComponent: function() {
var store = this.lookupViewModel().getStore(this.config.bind.store.replace(/[{}]/g, ''));
store.on('load', this.onLoad, this);
this.callParent();
},
只是为了再添加一个选项,您可以在网格上收听 reconfigure
事件,因为这是在绑定商店完成后触发的事件......所以这样的事情会起作用:
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');
}
});
我真的很难理解如何访问组件上的实际绑定存储实例,例如 ComboBox 或 Grid。看起来,当您使用他们的 getStore 方法时,它 returns 是一个不同的实例。
在我的 example 中,我有一个自定义网格 class,在它的 initComponent 中,我想添加一个加载侦听器。不幸的是,加载监听器永远不会被命中,但绑定存储的加载监听器会。您可以看到监听器是在加载商店之前设置的,所以这不是问题。看起来initComponent中的store实例是一个内存存储,所以此时绑定的store实例没有同步到组件。
我知道我可以在绑定存储上有一个加载监听器,但这是一个自定义网格 class,对于任何自定义网格 class,我希望设置一个监听器...所以我不想在我的代码中到处都这样做...我只想在一个 class 中执行此操作,因为它们都将执行相同的逻辑。
有人可以向我解释为什么我的自定义网格 class 的加载侦听器没有受到影响,我该怎么做才能解决这个问题?我能以某种方式访问绑定的商店实例吗?
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')
}
});
Can someone explain to me why my custom grid class's load listener is not getting hit, and what can I do to fix this?
您最初没有向您的网格提供任何商店(store
config option is required by the way). Hence the grid is creating its own, empty store as coded here:
store = me.store = Ext.data.StoreManager.lookup(me.store || 'ext-empty-store');
那个空的商店是让您的 onLoad
听众附加的商店。它没有被击中,因为商店从未加载过。
Can I somehow access the bound store instance?
是的,使用这个:
this.lookupViewModel().getStore('myStore')
您可以将您的侦听器附加到绑定存储而不是空存储,看看有什么不同。网格的空存储最终会被绑定的存储替换(毕竟这就是您在网格中看到数据的原因),但这发生在 initComponent
执行后。您可以通过覆盖 setStore
方法来跟踪将绑定存储设置到网格的时刻。
I know I can have a load listener on the bound store, but this is a custom grid class, and for any custom grid class, I want there to be a listener set up... so I don't want to have to do this all over the place in my code... I just want it in one class, as they're all going to have the same logic carried out.
由于您使用的是 MVVC,因此建议坚持该模式并保持视图仅声明视图方面。监听器应该在控制器中声明和处理(甚至不像你的例子那样在视图模型中)。否则,如果您继续坚持 Ext JS 5 之前的样式并将动态内容放入视图(即您的情况下的网格),则使用 MVVC 毫无意义。
这太骇人听闻了,我什至不想 post 将它作为答案,但为了 post 诚实起见,我将这样做。基于 Drake 的回答,我想出了如何使用在我的网格 class 的初始配置中传递的内容来获取我的商店。绑定与大括号一起出现,所以这就是我在其上执行 replace
的原因。就像我说的,这可能永远不应该使用,但它确实有用。
initComponent: function() {
var store = this.lookupViewModel().getStore(this.config.bind.store.replace(/[{}]/g, ''));
store.on('load', this.onLoad, this);
this.callParent();
},
只是为了再添加一个选项,您可以在网格上收听 reconfigure
事件,因为这是在绑定商店完成后触发的事件......所以这样的事情会起作用:
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');
}
});