Подтвердить что ты не робот

ExtJS 4: Модели с ассоциациями и магазинами

Введение

Я сталкиваюсь с проблемой разработки приложения с классом Ext.data.Model в ExtJS. Я попытаюсь развить свои идеи на очень распространенный сценарий онлайн-магазина здесь, чтобы вы могли следовать за мной. Я был бы очень признателен за любые комментарии к моим мыслям и выводам!

Модели

Предположим, вы хотите сопоставить тот факт, что "каждый клиент может заказать несколько продуктов" в ExtJS. Из голых слов можно определить эти три модели: Customer, Order и Product. Order в этом случае является тем, что соединяет Customer и Product с.

Ассоциации

Я обнаружил, что ExtJS фактически позволяет вам указать это отношение (Customer)1-n(Order)1-n(Product), используя классы Ext.data.HasManyAssociation и Ext.data.BelongsToAssociation. Но это то, что нужно? Вы хотите, чтобы a Product всегда принадлежал Order? Что делать, если вы хотите иметь список Product без какого-либо подключения к Order вообще?

Магазины

Здесь он становится более специфичным для ExtJS. В ExtJS у вас есть Ext.data.Store для хранения всех ваших данных. Для меня естественным способом организации моих данных является наличие Ext.data.Store для каждой из моих моделей:

  • CustomerStore
  • OrderStore
  • ProductStore

Подумайте, что у вас есть три Ext.grid.Panel бок о бок; по одному для каждого магазина. При выборе клиента в одной сетке его заказы автоматически отображаются во второй сетке. При выборе порядка во второй сетке соответствующие продукты появляются в третьей сетке.

Звучит это естественно? Если нет, прокомментируйте!

Объединяя все это

Итак, теперь у нас есть три вещи, которые нам нужно собрать:

  • Модели и их
  • Ассоциации (hasMany, belongsTo) и
  • Данные (Store s)

Можно ли определить связь только с одной стороны отношения Model-Model? Например, могу ли я указать Order hasMany Product, но не указывать, что a Product belongsTo an Order? Поскольку Product может принадлежать более чем одному Order. Поэтому я указываю, что ниже Product модель hasMany Order.

Вот модели в ExtJS:

Клиент

Ext.define('Customer', {
    extend   : 'Ext.data.Model',
    requires : [
        'Order',
    ],
    fields   : [
           {name : 'id',          type : 'int'},
           {name : 'lastname',    type : 'string'}
           {name : 'firstname',   type : 'string'}
    ],
    hasMany: 'Order' /* Generates a orders() method on every Customer instance */
});

Заказ

Ext.define('Order', {
    extend   : 'Ext.data.Model',
    fields   : [
            {name : 'id',          type : 'int'},
            {name : 'customer_id', type : 'int'}, /* refers to the customer that this order belongs to*/
            {name : 'date',        type : 'date'}
    ],
    belongsTo: 'Customer', /* Generates a getCustomer method on every Order instance */
    hasMany: 'Product' /* Generates a products() method on every Order instance */
});

Продукт

Ext.define('Product', {
    extend   : 'Ext.data.Model',
    fields   : [
            {name : 'id',          type : 'int'},
            {name : 'name',        type : 'string'},
            {name : 'description', type : 'string'},
            {name : 'price',       type : 'float'}
    ],
    /*
        I don't specify the relation to the "Order" model here
        because it simply doesn't belong here.

        Will it still work?
    */
    hasMany: 'Order'
});

И вот магазины:

CustomerStore

Ext.define('CustomerStore', {
    extend      : 'Ext.data.Store',
    storeId     : 'CustomerStore',
    model       : 'Customer',
    proxy   : {
        type   : 'ajax',
        url    : 'data/customers.json',
        reader : {
            type           : 'json',
            root           : 'items',
            totalProperty  : 'total'
        }
    }
});

OrderStore

Ext.define('OrderStore', {
    extend      : 'Ext.data.Store',
    storeId     : 'OrderStore',
    model       : 'Order',
    proxy   : {
        type   : 'ajax',
        url    : 'data/orders.json',
        reader : {
            type           : 'json',
            root           : 'items',
            totalProperty  : 'total'
        }
    }
});

ProductStore

Ext.define('ProductStore', {
    extend      : 'Ext.data.Store',
    storeId     : 'ProductStore',
    model       : 'Product',
    proxy   : {
        type   : 'ajax',
        url    : 'data/products.json',
        reader : {
            type           : 'json',
            root           : 'items',
            totalProperty  : 'total'
        }
    }
});

Вот пример (не я) с компаниями и их продуктами http://superdit.com/2011/05/23/extjs-load-grid-from-another-grid/. Он использует две Модели и два магазина, но ассоциации не определены.

Заранее благодарю

-Konrad

4b9b3361

Ответ 1

Konrad. Недавно я столкнулся с проблемой Models+Associations+Stores. Это был не очень приятный опыт. Вот что я узнал:

Скажем, у нас есть Store1, Store2, Model1, Model2, Grid1, Grid2. Grid1 использует Store1, Store1 использует Model1, и аналогично Grid2 использует Store2, Store2 использует Model2.

Пока все работает, данные загружаются и т.д.

Но теперь мы хотим добавить ассоциацию hasMany к Model1. Хорошо, мы добавляем конфигурацию Model1:

hasMany: {model: 'Model2', name: 'model2'}

После этого вы думаете, что вы можете заполнить Store2 данными в Grid1 itemclick, выполнив следующие действия:

Grid1.on('itemclick', function(view, item_which_uses_model1){
  //item_which_uses_model1.model2() supposed to return Model2 store
  item_which_uses_model1.model2().load();
}

Ожидается, что Grid2 будет заполнен данными о Grid1 itemclick. Но ничего не происходит. Выполняются запросы Actualy, получены ответы. Но Grid2 не заполнен данными.
И через некоторое время вы понимаете, что item_which_uses_model1.model2() НЕ НЕ Store2.

когда Model2 "видит", что он имеет связь с Model1, он создает собственный магазин Model1, который не равен Store2.

Это не круто, потому что Grid2 использует Store2.

Фактически вы можете взломать его, например, добавив в конфигурацию Grid2:

store: new Model1().model2(),

но что, если вы используете шаблон ExtJS mvc. Grid2 не должен знать ничего о Model1.

Я не рекомендую использовать associations в проектах реального мира. По крайней мере сейчас. Вместо этого используйте подход, который показан в вашем примере: Model + Store + Filtering.

Ответ 2

Все отлично работает в ExtJS 4, в первый раз просто сложно. Ну, первые несколько раз.

Да, вы можете не указывать принадлежность к этой дочерней группе и по-прежнему использовать ее в отношениях "Есть много".

В моем проекте у нас есть десятки моделей, многие из которых имеют глубокие отношения, и он отлично работает.

Что касается отношений Many-Many, вы должны либо иметь

Клиент - <CustomerOrder> - Заказ

Что такое три модели,

Или вы можете "подделать" его, выполнив кучу работы на сервере, чтобы притвориться, что заказчик HasMany Orders. Вложенный json может помочь здесь.

Ответ 3

Я полностью согласен с Molecular Man. Прочитав предварительную документацию ExtJS, она показала, что это хороший маршрут, когда вы используете структуру набора деревьев, распределенную в разных магазинах. Честно говоря, все это могло быть правдой только в том случае, если такая ассоциация каким-либо образом ссылалась на магазины для совершения звонков. Это не тот случай, из которого я протестировал. У ассоциаций моделей нет таких отношений. Фильтрация - лучший способ не отставать от последовательного обновления других сеток, чьи модели зависят от других.

Ответ 4

Обратите внимание, что ваше предположение:

(Заказчик) 1-п (Order) 1-п (продукт)

неверно. Ваша фактическая модель должна быть:

(Заказчик) 1-п (Order) п -n (Product)

Вот почему вы обнаружили также трудности с его моделированием с hasMany-belongsTo