Как использовать Ext.ComponentQuery.query с вложенными атрибутами в Sencha Touch?

Например

var myHardtoGetObj = topLevelView.down('someview[config.categoryCfg.id=1]')[0];

Это вызывает у меня "неперехваченную ошибку"

Дано :

Ext.define('SomeView', {
    xtype : 'someview',
    config : {
        categoryCfg : {
            id   : 5,
            name : 'someName' 
        }
    }
});

Это возможно?

Спасибо.

0
code4jhon 29 Авг 2014 в 09:02

3 ответа

Лучший ответ

Канонический способ сделать это - добавить настраиваемый сопоставитель псевдоклассов:

Ext.ComponentQuery.pseudos.hasCategoryId = function(components, selector) {
    var result = [],
        c, i, len;

    for (i = 0, len = components.length; i < len; i++) {
        c = components[i];

        if (c.config.categoryCfg && c.config.categoryCfg.id == selector) {
            result.push(c);
        }
    }

    return result;
}

Затем вы можете использовать этот псевдокласс как глобально с Ext.ComponentQuery.query, так и локально с такими методами, как query, down и т. Д .:

var allMatched, someComponent;

allMatched = Ext.ComponentQuery.query(':hasCategoryId(1)');
someComponent = myPanel.down(':hasCategoryId(42)');

Дополнительные способы снятия шкуры с кошки см. В документе ComponentQuery .

2
Alex Tokarev 12 Сен 2014 в 20:45
Большое спасибо, мне очень понравился этот подход.
 – 
code4jhon
12 Сен 2014 в 16:47
Где лучше всего заявить об этом псевдо? метод запуска контроллера, где я буду использовать псевдо?
 – 
code4jhon
12 Сен 2014 в 17:21
1
Ext.ComponentQuery является глобальным, и его псевдонимы также являются глобальными. Я бы предложил разместить этот код где-нибудь вверху, чтобы он был доступен во всем приложении.
 – 
Alex Tokarev
12 Сен 2014 в 20:51

Это действительно интересный вопрос. Кажется, что нет абсолютно простого решения, однако есть довольно быстрое решение. Вы можете изменить свой код просмотра на:

Ext.define('SomeView', {
   xtype : 'someview',
   config : {
       categoryCfg : {
           id   : 5,
           name : 'someName' 
       }
   },

   hasCategoryId: function (id) {
       return this.getCategoryCfg().id == id;
   }
});

Тогда вы можете сделать такой запрос:

Ext.ComponentQuery.query('someview{hasCategoryId(1)}');

Или

topLevelView.down('someview{hasCategoryId(1)}');

Примечание : синтаксис селектора - xtype {memberMethod ()} без пробела между ними. Таким образом, оба селектора должны совпадать (так же, как .class1.class2 в CSS). Также селекторы должны быть в этом порядке, потому что набор результатов фильтруется каждым селектором по порядку, и если некоторые из компонентов не имеют метода hasCategoryId, он будет прерван только с помощью '{hasCategoryId (1)}'

2
todinov 4 Сен 2014 в 13:48
Это действительно вариант, но, как сказал мне друг, интересно, насколько это эффективно по сравнению с использованием на самом деле атрибута...
 – 
code4jhon
5 Сен 2014 в 07:01

Хотя это не совсем ответ на вопрос, но вы можете немного поработать, чтобы заставить его работать.

Вы можете добавить метод обновления в свой nestedConfig, например,

Ext.define('myCoolClass', {
    config : {
        nestedConfig : {
            nestedId : 5
        },

        nestedId : null
    },

    updateNestedConfig: function (nestedConfig) {
        if (nestedConfig.nestedId) {
            this.setNestedId(nestedConfig.nestedId);
        }
    }
});

Благодаря этому у вас теперь есть доступ к обычному атрибуту запроса компонента.

Ext.ComponentQuery.query('[nestedId=555]')

В качестве примера. Если вы посмотрите на исходный код Sencha, они используют это довольно часто, как в NavigationView и TabPanels.

1
Ernesto Ramírez Romero 3 Сен 2014 в 20:16
Дважды вложенныйId не звучит правильно в этом случае, я просто вообще избавлюсь от nestedConfig и определяю все атрибуты на уровне конфигурации... плюс мне придется создать еще одну функцию только для установки значения...
 – 
code4jhon
3 Сен 2014 в 20:36
Кстати, в соглашении говорится, что это должен быть «MyCoolClass»;)
 – 
code4jhon
12 Сен 2014 в 16:04