如何解决当需要父视图模型时,Extjs使用子视图模型数据
请考虑以下代码段(可以在https://fiddle.sencha.com/上运行,并在右上角的组合框中选择经典而不是现代):
Ext.define('ReusableComponent',{
xtype: 'reusable',extend: 'Ext.Container',config: {
foo: 'Foo'
},updateFoo: function(foo) {
this.getviewmodel().set('foo',foo);
},viewmodel: {
data: {
foo: 'Foo'
}
},items: [{
bind: {
html: 'foo = {foo}'
}
}]
});
Ext.define('ConcreteComponent',{
extend: 'Ext.panel.Panel',viewmodel: {
data: {
foo: 'Bar'
}
},layout: 'fit',items: [{
xtype: 'reusable',bind: {
foo: '{foo}'
}
}]
});
Ext.application({
name : 'fiddle',launch : function() {
Ext.create('ConcreteComponent',{
renderTo: Ext.getBody(),title: 'ConcreteComponent',width: 200,height: 200
});
}
});
梦想是拥有一个可重用的组件,该组件将具有已定义的外部接口,并且知道它应该足够了。那些使用该组件的人不必知道其内部。在此示例中,外部接口是通用配置,它继承自Ext.Container(例如width / height / etc)和foo
配置。
所以说我然后尝试在ConcreteComponent中使用它。我知道可重用组件具有config foo,因此我应该能够将其绑定到自己的viewmodel,这就是我要做的。但是,这不起作用,它显示foo = Foo
,而不是(预期的)foo = Bar
。似乎很清楚为什么-我不知不觉使用了孩子的视图模型中已经存在的名称,而extjs选择了该名称,而不是我在ConcreteComponent中定义的名称。同样清楚的是如何对其进行创可贴修复(例如,在ConcreteComponent中,将viewmodel数据属性从foo
重命名为foo2
)。 但这迫使人们知道该可重用组件的内部结构,而不仅仅是其公共界面。反正有解决办法吗?还是应该将子视图模型始终视为其公共界面的一部分?
解决方法
看起来解决方案是简单地在私有属性下手动创建一个视图模型(这会分解extjs在组件的视图模型与其容器的视图模型https://docs.sencha.com/extjs/6.2.0/classic/Ext.Component.html#cfg-viewModel之间创建的子父链),并将其传递给可重用的组件子级通过viewModel配置显式。使用defaults
似乎可以正常工作。绊倒拾色器的源代码https://docs.sencha.com/extjs/6.2.0/classic/src/Selector.js.html时,我看到了解决方案。这是问题的固定代码
Ext.define('ReusableComponent',{
xtype: 'reusable',extend: 'Ext.Container',config: {
foo: 'Foo'
},updateFoo: function(foo) {
this.childViewModel.set('foo',foo);
},constructor: function() {
this.childViewModel = Ext.create('Ext.app.ViewModel',{
data: {
foo: 'Foo'
}
});
this.defaults = {
viewModel: this.childViewModel
};
this.callParent(arguments);
},items: [{
bind: {
html: 'foo = {foo}'
}
}]
});
Ext.define('ConcreteComponent',{
extend: 'Ext.panel.Panel',viewModel: {
data: {
foo: 'Bar'
}
},layout: 'fit',items: [{
xtype: 'reusable',bind: {
foo: '{foo}'
}
}]
});
Ext.application({
name : 'Fiddle',launch : function() {
Ext.create('ConcreteComponent',{
renderTo: Ext.getBody(),title: 'ConcreteComponent',width: 200,height: 200
});
}
});
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。