ExtJS5 - модель и схема
Здравствуйте.
Пытаюсь реализовать пример по работе с моделями и схемой. Нашел вот этот ресурс: http://www.sencha.com/products/extjs...s-data-package и начал пробовать. Базовая модель: Ext.define("Communication.model.Base", { extend: "Ext.data.Model" ,schema: { namespace: 'Communication.model', // remove this pattern from entity names proxy: { // Ext.util.ObjectTemplate type: "ajax", url: "/json?cmd=communication.api&entity={entityName}", reader: { type: "json", rootProperty: "{entityName:lowercase}" } } } }); От нее наследую: Ext.define("Communication.model.layout.Tabs", { extend: "Communication.model.Base", fields: [ "name" ] }); EntityName получается "layout.Tabs". С сервера возвращаю json, созданный из следующей структуры: my $data = { "layout.tabs" => [ {name=>"Summary"}, {name=>"Access"}, {name=>"s1"}, {name=>"s2"}, ] }; Но вот когда я эту модель ("Communication.model.layout.Tabs") подключаю к стору и загружаю его, он не видит данные. var store = new Ext.data.Store ({ model: "Communication.model.layout.Tabs" }); store.load({ callback:function(records, operation, success){ console.log(success); console.log(records); } }); В логе я вижу что success=true, но records - пустой массив. Если я формирую json как простой массив, не используя rootProperty, то данные приходят нормально. Вопрос: зачем тогда вообще этот параметр? Я чего то не понимаю... Как им пользоваться? |
rootProperty: "{entityName:lowercase}"
я честно говоря с таким механизмом не работал, могу предположить, что {entityName:lowercase} заменяет на какое то значение, нет? и что приходит с сервера? |
Я же писал... если json с сервера включает в себя rootProperty и в нем уже данные то в сторе пусто. Если отправляю просто массив - в сторе то что нужно.
|
Попробовал разобраться, но не проверял...
{ rootProperty: "{entityName:lowercase}" } По частям: rootProperty - имя ключа в приходящем с сервера JSONe, который содержит массив данных/записей/строк. В нашем случае - "layout.tabs". entityName - название модели, причём урезанное. От полного имени класса модели отрезается первая часть, которая указана в нашем случае здесь: { schema: { namespace: 'Communication.model' } } Т.е.: "Communication.model.layout.Tabs" - 'Communication.model' = "layout.Tabs" lowercase - имя функции для преобразования имени модели. Ожидаем, что из урезанного имени модели "layout.Tabs" в результате этого преобразования получится ключ в присылаемом с сервера JSONe "layout.tabs". Смотрите подробнее в разделе "Relative Naming": Ext.data.schema.Schema В нашем случае, неймер в schema не указан, используется дефолтный. С этой точки зрения, код написан верно и должен работать. Меня насторожили некоторые вещи. Например, в исходниках Ext.data.schema.Namer я не обнаружил lowercase. Там только присутствуют: undotted, uncapitalize, pluralize, underscore, singularize. Может в этом дело? |
novikov, спасибо за наводку. Буду смотреть.
У меня вот назрел еще вопрос: а зачем вообще модель как сущность, что она дает? Я пока вижу что в ней можно определить схему, это плюс к стандартизации запросов. А еще? Я думал там есть некий механизм контроля, иными словами попытка вызвать get с неопределенным в модели полем должна привести к варнингу хотя бы... Но нет, ничего подобного. Вы не могли бы в нескольких фразах написать плюсы моделей? |
В 5 версии стало необязательным перечисление всех полей.
It may seem contradictory in this context, but in Ext JS 5, you are no longer required to declare a Model’s fields. Чтобы задействовать валидацию поля, нужно в его определение добавить: { validators: ['presence'] } Валидатор можно написать кастомный. По ссылке выше ещё говорят о том, что упростилась работа с внешними ключами. Данные в связанные модели должны подгрузиться автоматом, если в модели определён прокси. Модели могут использоваться в формах. Модели нужны для определения сторов/хранилищ. В них они используются для хранения состояния записи - "изменена" и "удалена". Это полезно для отправки пакетных запросов на сервер, а не одиночных. |
Хорошо, а вот у меня как назрел еще вопрос по моделям )
Есть например модель для авторов: айди и имя. Есть модель для книг: айди книги, айди автора, заголовок. Теперь я хочу вывести список книг. Делаю грид, в сторе указываю модель "книга". Вопрос: как отобразить имя автора вместо его айди? Переписать рендерер в гриде? Или есть более "умные" методы? |
Infarch, Вы разобрались в этом вопросе? У меня он как раз назрел сейчас :)
Тут вот: http://moduscreate.com/associations-in-ext-js-5/ Пишут что все должно быть максимально просто. Указал reference в поле и в ответ уже должны идти связанные данные. Есть базовая модель у меня: Ext.define('MyApp.model.Base', { extend: 'Ext.data.Model', schema: { namespace: 'MyApp.model' } }); Модель должностей: Ext.define('MyApp.model.dictionaries.positions.Positions', { extend: 'MyApp.model.Base', fields: [ { type: 'int', name: 'id' }, { type: 'string', name: 'value' }, { type: 'string', name: 'valueEn' }, ], proxy: { type: 'api', url: MyApp.Global.getApiUrl() + 'api/v1/positions' } }); Модель сотрудников: Ext.define('MyApp.model.employees.Employees', { extend: 'MyApp.model.Base', fields: [ { type: 'int', name: 'id' }, { name: 'profile_pic' }, { type: 'string', name: 'lastname' }, { type: 'string', name: 'firstname' }, { type: 'string', name: 'middlename' }, { type: 'int', name: 'positionId', reference: 'dictionaries.positions.Positions' } ], proxy: { type: 'api', url: MyApp.Global.getApiUrl() + 'api/v1/employees' } }); Указал я reference, но связанных данных не вижу. |
Я не разобрался в свое время и отказался от такой идеи. Ибо по всему выходило что надо писать рендерер для такой колонки и в нем уже извлекать данные. Вместо этого я просто стал читать с сервера комбинированные списки.
А по той ссылке что вы дали я вижу ту самую идею. Они так и пишут: If you inspect the Customers store, you’ll see that each record now has an addresses() getter that will return a store of this customer’s addresses.. Мы получаем геттер, но чтоб вывести его результат в списке нам таки нужен рендерер. |
Цитата:
Разобрался со связями, но для меня оказалось проще использовать денормализацию (+1 поле в БД) вместо манипуляций с рендерером. Вот хороший Фидл по теме: https://fiddle.sencha.com/#fiddle/1h22 Несколько моментов: 1. Нормально это все работает только если использовать механизм сессий. Если даже в фиддле этом закомментировать session: true в 3х местах, то все нахрен отвалится. 2. Обязательно все store прописывать через ViewModel, у которых также включать сессию. Без сессии и ViewModel на каждую связанную запись будет идти запрос в БД! 3. В рендерере надо также отлавливать NULL, если он есть и выдавать вместо него пустую строку (может есть какая опция на эту тему, но пока не нашел). 3. Группировка по связанному полю в Grid'е работает, но фильтрация уже, увы, недоступна. |
Поясните, что означает 132 строчка в филде в Вашем примере
parent: this.getViewModel() интересует "смысловая нагрузка", для чего это ? |
Пример не мой, а с форума Сенчи. Я не использовал эту строку вообще у себя и все отлично работало.
|
Часовой пояс GMT +3, время: 17:17. |