好像我对绑定时间有一些误解。我有一个简单的组合框,其值绑定到viewmodel中的某个对象。选择新值,触发更改事件,在setValue方法之后触发,因此我的新值已经设置,但我的viewmodel尚未更新。什么时候我的viewmodel会更新?我找到了一些关于调度程序的信息,它说我需要运行notify()方法立即将更改应用于viewmodel,但它根本没有帮助我。
Ext.define('MyModel', {
extend: 'Ext.data.Model',
idProperty: 'foo',
fields: [{
name: 'bar',
type: 'string'
}]
});
Ext.define('MyViewModel',{
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.my',
data: {
testObj: {
foo: null,
bar: null
}
},
stores:{
combostore: {
model: 'MyModel',
data: [{
foo: '1',
bar: 'qwerty'
},{
foo: '2',
bar: 'ytrewq'
}]
}
}
});
Ext.define('MyViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.my',
onChange: function() {
var vm = this.getViewModel();
vm.notify();
console.log(vm.get('testObj.foo'));//supposed to be current value
}
});
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.create('Ext.container.Viewport', {
controller: 'my',
viewModel: {
type: 'my'
},
layout : 'vbox',
items : [
{
xtype : 'combo',
valueField: 'foo',
displayField: 'bar',
queryMode: 'local',
bind: {
store: '{combostore}',
value: '{testObj.foo}'
},
listeners:{
change: 'onChange'
}
}
]
});
}
});
我知道这是一个迟到的回应,但我认为这个问题仍然存在。看到这个小提琴:https://fiddle.sencha.com/#fiddle/2l6m&view/editor。
基本上,我们的想法是您监听绑定变量而不是监听组合框选择更改(这会触发绑定变量的重新评估)。
关键代码在我为视图模型添加的构造函数中:
Ext.define('MyViewModel',{
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.my',
// added this to enable the binding
constructor: function () {
var me = this;
me.callParent(arguments);
me.bind('{selectedItem}', function (value) {
console.log('combobox selected item changed (bar value): ' + (value === null ? "null": value.get('bar')));
console.log(me.getView().getController());
});
me.bind('{testObj.foo}', function (value) {
console.log('combobox value (foo value): ' + value);
// you can access the controller
console.log(me.getView().getController());
});
},
data: {
testObj: {
foo: null,
bar: null
},
selectedItem: null,
},
stores:{
combostore: {
model: 'MyModel',
data: [{
foo: '1',
bar: 'qwerty'
},{
foo: '2',
bar: 'ytrewq'
}]
}
}
});
这是视图(注意与选择的绑定):
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.create('Ext.container.Viewport', {
controller: 'my',
viewModel: {
type: 'my'
},
layout : 'vbox',
items : [
{
xtype : 'combo',
valueField: 'foo',
displayField: 'bar',
queryMode: 'local',
bind: {
store: '{combostore}',
value: '{testObj.foo}',
selection: '{selectedItem}'
},
listeners:{
change: 'onChange'
}
}
]
});
}
});
绑定选择不是必需的,但我将其作为另一个选项包括在内,因为有时您可能希望在绑定到列表的商店中存储其他数据。
我希望这有助于其他人。
您不应该直接在viewmodel上调用notify。它是私人的:http://docs.sencha.com/extjs/5.0/5.0.1-apidocs/#!/api/Ext.app.ViewModel-method-notify
只需通过调用vm.setData({})来设置数据。
onChange: function(cb, newValue, oldValue) {
var vm = this.getViewModel();
console.log('newValue', newValue);
console.log('oldValue', oldValue);
this.getViewModel().setData({'testObj': {'foo': newValue}});
console.log(vm.get('testObj.foo'));//supposed to be current value
}
从来没有考虑过以下示例,我使用公式来获取组合框的选定模型。看到我删除了监听器,添加了对组合框的引用并创建了一个公式以深入绑定到所选记录。
Ext.define('MyModel', {
extend: 'Ext.data.Model',
idProperty: 'foo',
fields: [{
name: 'bar',
type: 'string'
}]
});
Ext.define('MyViewModel',{
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.my',
data: {
testObj: {
foo: null,
bar: null
}
},
stores:{
combostore: {
model: 'MyModel',
data: [{
foo: '1',
bar: 'qwerty'
},{
foo: '2',
bar: 'ytrewq'
}]
}
},
formulas: {
currentRecord: {
bind: {
bindTo: '{myCombo.selection}',
deep: true
},
get: function(record) {
return record;
},
set: function(record) {
this.set('currentRecord', record);
}
}
}
});
Ext.define('MyViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.my',
onChange: function(cb, newValue, oldValue) {
var vm = this.getViewModel();
console.log('newValue', newValue);
console.log('oldValue', oldValue);
this.getViewModel().setData({'testObj': {'foo': newValue}});
console.log(vm.get('testObj.foo'));//supposed to be current value
}
});
Ext.application({
name : 'Fiddle',
launch : function() {
var vp = Ext.create('Ext.container.Viewport', {
controller: 'my',
viewModel: {
type: 'my'
},
layout : 'vbox',
items : [
{
xtype : 'combo',
reference: 'myCombo',
valueField: 'foo',
displayField: 'bar',
queryMode: 'local',
bind: {
store: '{combostore}',
value: '{testObj.foo}'
}/*,
listeners:{
change: 'onChange'
}*/
},
{
xtype: 'label',
bind: {
text: '{currentRecord.foo}'
}
}
]
});
/* Just an example. You could also select records on the combo itself */
vp.getViewModel().setData({'testObj': {'foo': '2'}});
}
});
推迟将是你的救世主:
onChange: function() {
var vm = this.getViewModel();
Ext.defer(function(){
console.log(vm.get('testObj.foo'));//supposed to be current value
},10,this);
}
请使用select
事件而不是change
。
我认为更改事件甚至在设置值之前就会触发。