组件查询找到静态配置但未以编程方式添加
Component Query finds static config but not programmatically added
在我们的 ExtJs 5.0.1 项目中,我们创建组件并在 运行时 添加额外的 css 类 有条件的。
我们想通过组件查询找到它们,但是对于以编程方式添加的 css 类.
但是当我们在组件配置中硬编码定义它们时,查询 returns 预期结果。
我们如何获取对以编程方式添加的组件的引用 css 类?
示例视图:
Ext.define('T.view.Main',{
extend: 'Ext.panel.Panel',
title: 'test',
cls: 'working', // static config
initComponent: function(){
this.callParent(arguments);
this.addCls('notworking'); // added at runtime
}
});
示例应用程序:
Ext.application({
name : 'T',
autoCreateViewport: 'T.view.Main',
launch: function(){
// the cls "working" assigned as config to the Main View is found by
// the ComponentQuery
var working = Ext.ComponentQuery.query('[cls~=working]');
// the cls "notWorking" assigned by addCls during runtime to the Main View
// is not found by the ComponentQuery
var notWorking = Ext.ComponentQuery.query('[cls~=notworking]');
Ext.Msg.alert('Static vs Dynamic', 'working: ' + working.length + ' notWorking: ' + notWorking.length);
}
});
更新
@Alexander 建议在调用 callParent 之前添加额外的 cls,这听起来像是一个显而易见的解决方案,但现在组件查询甚至找不到 .working
cls。
Ext.define('T.view.Main',{
extend: 'Ext.panel.Panel',
title: 'test',
cls: 'working', // static config
initComponent: function(){
this.cls += ' notworking';
this.callParent(arguments);
}
});
查看更新后的 Sencha Fiddle。
更新 2
我可能在 Component.js 代码中发现了问题,在构造函数中发生了以下情况
constructor: function (config) {
...
me.setupProtoEl();
// initComponent, beforeRender, or event handlers may have set the style or `cls` property since the `protoEl` was set up
// so we must apply styles and classes here too.
if (me.cls) {
me.initialCls = me.cls;
me.protoEl.addCls(me.cls);
}
if (me.style) {
me.initialStyle = me.style;
me.protoEl.setStyle(me.style);
}
me.renderData = me.renderData || {};
me.initComponent();
...
- proto el 由
me.setupProtoEl();
用一些 css 类 初始化
- 检查是否设置了
cls
,然后将其应用于原型元素并保存到initialCls 属性
- initComponent 函数被调用,当
cls
在其中改变时,构造函数不再注意到它
在我看来,第 2 步和第 3 步需要互换,以便识别 initComponent 函数中 cls
的变化。
cls
是一个配置属性,供你指定CSSclass。但是 addCls
不会更新它 - 它只是更新基础 DOM 元素上的 class 属性。
addCls: function(cls) {
var me = this,
el = me.rendered ? me.el : me.protoEl;
el.addCls.apply(el, arguments);
return me;
},
(source)
因为 addCls
不更新 cls
属性,您的 ComponentQuery 调用无法通过这种方式找到它。
至于你如何解决你的问题:最简单的方法是在你更新的 class 上添加你自己的 属性,同时添加 [=25] =].然后您可以对您的自定义 属性 进行组件查询。尽管我会包括您的 class 的 xtype,以避免潜在的命名空间冲突。
正如@RobertWatkins 指出的那样,组件的 cls 没有被 addCls
改变,它只是更新了 DOM 元素。
在运行时设置 cls
配置的解决方案是在组件构造函数中执行。然后将 cls 应用于 DOM 元素和组件。组件查询现在可以找到它。
cls: 'working',
constructor: function (config) {
this.cls += ' nowworking';
this.callParent(arguments);
},
对应的应用程序片段
// the component is retrieved
var working = Ext.ComponentQuery.query('[cls~=working]');
// the component is retrieved aswell
var nowWorking = Ext.ComponentQuery.query('[cls~=nowworking]');
工作 fiddle.
在我们的 ExtJs 5.0.1 项目中,我们创建组件并在 运行时 添加额外的 css 类 有条件的。 我们想通过组件查询找到它们,但是对于以编程方式添加的 css 类.
但是当我们在组件配置中硬编码定义它们时,查询 returns 预期结果。
我们如何获取对以编程方式添加的组件的引用 css 类?
示例视图:
Ext.define('T.view.Main',{
extend: 'Ext.panel.Panel',
title: 'test',
cls: 'working', // static config
initComponent: function(){
this.callParent(arguments);
this.addCls('notworking'); // added at runtime
}
});
示例应用程序:
Ext.application({
name : 'T',
autoCreateViewport: 'T.view.Main',
launch: function(){
// the cls "working" assigned as config to the Main View is found by
// the ComponentQuery
var working = Ext.ComponentQuery.query('[cls~=working]');
// the cls "notWorking" assigned by addCls during runtime to the Main View
// is not found by the ComponentQuery
var notWorking = Ext.ComponentQuery.query('[cls~=notworking]');
Ext.Msg.alert('Static vs Dynamic', 'working: ' + working.length + ' notWorking: ' + notWorking.length);
}
});
更新
@Alexander 建议在调用 callParent 之前添加额外的 cls,这听起来像是一个显而易见的解决方案,但现在组件查询甚至找不到 .working
cls。
Ext.define('T.view.Main',{
extend: 'Ext.panel.Panel',
title: 'test',
cls: 'working', // static config
initComponent: function(){
this.cls += ' notworking';
this.callParent(arguments);
}
});
查看更新后的 Sencha Fiddle。
更新 2
我可能在 Component.js 代码中发现了问题,在构造函数中发生了以下情况
constructor: function (config) {
...
me.setupProtoEl();
// initComponent, beforeRender, or event handlers may have set the style or `cls` property since the `protoEl` was set up
// so we must apply styles and classes here too.
if (me.cls) {
me.initialCls = me.cls;
me.protoEl.addCls(me.cls);
}
if (me.style) {
me.initialStyle = me.style;
me.protoEl.setStyle(me.style);
}
me.renderData = me.renderData || {};
me.initComponent();
...
- proto el 由
me.setupProtoEl();
用一些 css 类 初始化
- 检查是否设置了
cls
,然后将其应用于原型元素并保存到initialCls 属性 - initComponent 函数被调用,当
cls
在其中改变时,构造函数不再注意到它
在我看来,第 2 步和第 3 步需要互换,以便识别 initComponent 函数中 cls
的变化。
cls
是一个配置属性,供你指定CSSclass。但是 addCls
不会更新它 - 它只是更新基础 DOM 元素上的 class 属性。
addCls: function(cls) {
var me = this,
el = me.rendered ? me.el : me.protoEl;
el.addCls.apply(el, arguments);
return me;
},
(source)
因为 addCls
不更新 cls
属性,您的 ComponentQuery 调用无法通过这种方式找到它。
至于你如何解决你的问题:最简单的方法是在你更新的 class 上添加你自己的 属性,同时添加 [=25] =].然后您可以对您的自定义 属性 进行组件查询。尽管我会包括您的 class 的 xtype,以避免潜在的命名空间冲突。
正如@RobertWatkins 指出的那样,组件的 cls 没有被 addCls
改变,它只是更新了 DOM 元素。
在运行时设置 cls
配置的解决方案是在组件构造函数中执行。然后将 cls 应用于 DOM 元素和组件。组件查询现在可以找到它。
cls: 'working',
constructor: function (config) {
this.cls += ' nowworking';
this.callParent(arguments);
},
对应的应用程序片段
// the component is retrieved
var working = Ext.ComponentQuery.query('[cls~=working]');
// the component is retrieved aswell
var nowWorking = Ext.ComponentQuery.query('[cls~=nowworking]');
工作 fiddle.