组件查询查找静态配置但未以编程方式添加

时间:2015-12-02 15:44:24

标签: extjs extjs5 extjs6

在我们的 ExtJs 5.0.1 项目中,我们创建了组件,在运行时,我们添加了其他 css类条件。 我们希望通过组件查询查找它们,但组件查询不会为编程添加的css类返回任何内容

但是当我们在组件配置中对它们进行硬编码时,查询会返回预期的结果。

如何通过编程方式添加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();
    ...
  1. 原型用me.setupProtoEl();
  2. 初始化了一些css类
  3. 检查是否设置了cls,然后将其应用于proto元素并保存到initialCls属性
  4. 调用initComponent函数,当其中更改cls时,构造函数不再注意到它
  5. 在我看来,需要交换步骤2和3,以便识别initComponent函数中cls的更改。

2 个答案:

答案 0 :(得分:3)

cls是一个配置属性,供您指定CSS类。但是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调用无法找到它。

关于如何解决问题:最简单的方法是在添加类的同时在更新的类上添加自己的属性。然后,您可以对自定义属性执行组件查询。虽然我会包含你的类的xtype,以避免潜在的命名空间冲突。

答案 1 :(得分:1)

由于@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