Ext JS MVVM技巧:第二部分。ViewModel隔离





5.00/5 (3投票s)
完成第一部分并实现ViewModel隔离
引言
在第一部分中,我们已经更进一步地实现了组件的封装。我们解决了外部绑定问题,并使内部绑定成为可能。 在本部分中,我们将解决在层次结构中可能发生的ViewModel
数据字段名称冲突问题。
名称冲突
假设我们正在创建两个组件,一个外部组件和一个内部组件。我们不想暴露组件的内部细节,因此希望使用配置来操作其状态。在这种情况下,每个组件都有一个非唯一的color
配置。
为了使实验更清晰,我们不会使用第一部分中的修复方案。我们更改了处理程序中的ViewModel
。外部组件的color
绑定到文本字段、标签以及内部组件的color
配置。
Ext.define('Fiddle.view.OuterContainer', {
// ...
viewModel: {
data: {
color: null
}
},
config: {
color: null
},
items: [{
xtype: 'textfield',
fieldLabel: 'Enter color',
bind: '{color}',
listeners: {
change: 'colorField_change'
}
}, {
xtype: 'displayfield',
fieldLabel: 'Color',
bind: '{color}'
}, {
xtype: 'innercontainer',
bind: {
color: '{color}' // <<-- non-unique
}
}],
colorField_change: function (field, value) {
this.setColor(value);
},
updateColor: function (color) {
this.getViewModel().set('color', color);
}
});
Ext.define('Fiddle.view.InnerContainer', {
// ...
viewModel: {
data: {
color: null
}
},
config: {
color: null
},
items: [{
xtype: 'textfield',
fieldLabel: 'Color',
bind: '{color}'
}],
updateColor: function (color) {
this.getViewModel().set('color', color);
}
});
如果我们尝试这样做,会发现绑定无法正常工作。原因是两个ViewModel
都包含color
数据字段。为了避免这个问题,我们应该对它们进行唯一命名。但这是否方便?这是否能保证唯一性?
扩展
因此,创建了SplitViewModel
扩展。它为ViewModel
的数据字段提供唯一的内部名称。结果是,ViewModel
之间永远不会相互干扰。为了完成我们的示例,我们将创建一个显式的反向引用绑定,如下所示
Ext.define('Fiddle.view.OuterContainer', {
// ...
viewModel: {
name: 'outercontainer',
data: {
color: null
}
},
// ...
items: [{
xtype: 'innercontainer',
bind: {
color: '{outercontainer|color}'
}
}]
// ...
});
这里发生了什么变化?
我们为外部ViewModel
指定了一个name
,因为它是在同一个文件中定义的匿名ViewModel。无论如何,name
都会自动从alias
中获取。
我们使用name
和|
字符,为外部ViewModel
指定了一个显式的反向引用:'{outercontainer|color}'
。
结果
ViewModel
现在彼此隔离。我们可以使用ViewController
和ViewModel
创建独立的视图,而无需担心ViewModel
之间的干扰。有了这个扩展,绑定变得非常可预测。
限制
如果您有嵌套的视图,都带有ViewModel
,就像上面的示例一样,那么您必须在必要时为您的绑定添加显式的反向引用。即使属性名称是唯一的。您所需要做的就是添加ViewModel
的name
或type
,然后在属性名称前加上|
字符。
Using the Code
在GitHub上找到扩展
并导入它
Ext.application({
requires: [
'Ext.vmx.app.SplitViewModel'
]
});
组合扩展
我发现当同时使用这两个扩展时,结果令人印象深刻(第一部分)。请查看此示例
没有单个处理程序。一切都通过声明式语法完成。组件的状态由配置属性控制,但内部细节通过ViewModel
绑定。我希望Sencha默认情况下就这样做。