Как мне использовать древовидное хранилище с «автоматическими» сопоставлениями?

#tree #sencha-touch

#дерево #сенча-касание

Вопрос:

У меня есть модель, которая выглядит следующим образом:

 Ext.regModel('TreeItem', {
    fields: [
             { name: 'ItemId', type: 'int' },
             { name: 'ItemType', type: 'string' },
             { name: 'Article', type: 'auto' },
             { name: 'Container', type: 'auto' },
             { name: 'Category', type: 'auto'}]
});
  

ItemType указывает, должен ли этот конкретный элемент отображаться как статья, контейнер или категория. Каждый из объектов Article, Container и Category имеет связанные ArticleName, ContainerName и CategoryName.

Я хотел бы отобразить эти имена в вложенном списке на основе ItemType записи. Итак, я переопределил getItemTextTpl следующим образом:

 getItemTextTpl: function (recordnode)
            {
                var template = '<div class="{ItemType}-icon"></div>';
                if (recordnode.firstChild.attributes.record.data["ItemType"] == 'Article')
                {
                    template  = recordnode.firstChild.attributes.record.data['Article']["ArticleName"];
                }
                if (recordnode.firstChild.attributes.record.data["ItemType"] == 'Container')
                {
                    template  = recordnode.firstChild.attributes.record.data['Container']["ContainerName"];
                }
                if (recordnode.firstChild.attributes.record.data["ItemType"] == 'Category')
                {
                    template  = recordnode.firstChild.attributes.record.data['Category']["CategoryName"];
                }
                return template;   
            }
  

Однако, похоже, что getItemTextTpl вызывается только один раз для каждого уровня дерева, поэтому нет способа отобразить информацию для каждого элемента списка.

У кого-нибудь есть предложения о том, как это сделать? Заранее спасибо.

Ответ №1:

Вы должны перенести свою условную логику из функции в шаблон. Вот пример, который демонстрирует, как вы могли бы это сделать (хотя вам, вероятно, придется изменить его, чтобы заставить его работать):

 getItemTextTpl: function (recordnode)
    {
        var template = '<div class="{ItemType}-icon"></div>'  
            '<tpl if="ItemType === 'Article'">'  
                '{ArticleName}'  
            '</tpl>'  
            '<tpl if="ItemType === 'Container'">'  
                '{ContainerName}'  
            '</tpl>'  
            '<tpl if="ItemType === 'Category'">'  
                '{CategoryName}'  
            '</tpl>'  
        '</div>';
        return template;   
    }
  

Я создал демонстрационную версию NestedList, которая использует эту технику. Код находится на github, и там также есть скринкаст, демонстрирующий, как он был создан. Возможно, вы также захотите ознакомиться с моей серией скринкастов из двух частей на тему Xtemplates (часть первая и часть вторая)

Комментарии:

1. Да, это то, что я бы сделал, но каждое из имен находится внутри автоматических сопоставлений с объектами article, container и category, и я бы предпочел не удалять их, потому что в этих объектах много другой информации, которую я хотел бы использовать для обеспечения очень насыщенного отображения. (Приведенный выше код — всего лишь пример.) Можно ли получить доступ к атрибутам автообъектов в шаблоне?

2. Я думаю, что должна быть возможность перевести ваши условия javascript в <tpl if=""/> формат, но необходимость экранировать определенные символы делает его уродливым и неприятным для чтения. В этой ситуации я бы обычно рекомендовал переместить встроенные условные обозначения из <tpl> тегов в функции-члены. Но, к сожалению, я не знаю ни одного способа прикрепить функцию-член в этом контексте, потому что getItemTextTpl предполагается, что она возвращает объект string, а не XTemplate.

Ответ №2:

Это невозможно сделать. Я обобщил свои объекты и использовал обычные сопоставления. Вы не можете использовать автоматические сопоставления с шаблоном.