32

序章

Ext.data.ModelExtJSのクラスでアプリケーション設計の問題に直面しています。ここでは、私のアイデアを非常に一般的なオンライン ストアのシナリオに展開しようとします。私の考えや結論についてコメントをいただければ幸いです。

モデル

「すべての顧客が複数の製品を注文できる」という事実を ExtJS にマッピングするとします。素の言葉から、関係する次の 3 つのモデルを識別できます: CustomerOrder、およびProduct。このOrder場合の は、Customers と Products を接続するものです。

協会

ExtJS では、およびクラス(Customer)1-n(Order)1-n(Product)を使用してこの関係を実際に指定できることがわかりました。しかし、これは人が望むものですか?が常に に属していることを望みますか? s とはまったく関係のない s のリストが必要な場合はどうすればよいでしょうか。Ext.data.HasManyAssociationExt.data.BelongsToAssociationProductOrderProductOrder

店舗

これは、より ExtJS 固有のものになります。ExtJS では、Ext.data.Storeすべてのデータを保持する s があります。私にとって、データを整理する自然な方法Ext.data.Storeは、モデルごとに forを持つことです。

  1. CustomerStore
  2. OrderStore
  3. ProductStore

Ext.grid.Panel3 つの s を並べて配置することを検討してください。店舗ごとに1つ。1 つのグリッドで顧客を選択すると、その注文が 2 番目のグリッドに自動的に表示されます。2 番目のグリッドで注文を選択すると、関連する製品が 3 番目のグリッドに表示されます。

これはあなたにとって自然に聞こえますか?そうでない場合は、コメントしてください!

すべてをまとめる

したがって、ここでまとめる必要があるのは次の 3 つです。

  1. モデルとその
  2. 関連 ( hasManybelongsTo) および
  3. データStore_

モデル-モデル関係の片側からのみ関連付けを定義することは可能ですか? たとえば、Order hasMany Products を指定して an を除外することはProduct belongsToできOrderますか? aProductは実際には複数の に属することができるため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'
});

そして、以下が店舗です。

カスタマーストア

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'
        }
    }
});

オーダーストア

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'
        }
    }
});

製品ストア

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/ . 2 つのモデルと 2 つのストアを使用しますが、関連付けの定義はありません。

前もって感謝します

-コンラッド

4

4 に答える 4

15

コンラッド。私は最近、を扱うことに直面しましたModels+Associations+Stores。これはあまり楽しい経験ではありませんでした。これが私が学んだことです:

Store1、Store2、Model1、Model2、Grid1、Grid2があるとしましょう。Grid1はStore1を使用し、Store1はModel1を使用し、同様にGrid2はStore2を使用し、Store2はModel2を使用します。

これまでのところ、すべてが機能しており、データが読み込まれています。

しかし、ここでhasManyModel1に関連付けを追加します。OK、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's store
  item_which_uses_model1.model2().load();
}

Grid2にGrid1のデータが入力されていることを期待していますitemclick。しかし、何も起こりません。実際にリクエストが投稿され、レスポンスが得られます。ただし、Grid2にはデータが入力されていません。
そしてしばらくすると、それはそうではitem_which_uses_model1.model2() ない Store2ことに気づきます。

Model2がModel1と関連付けられていることを「認識」すると、Store2と等しくないModel1自身のストアを作成します。

Grid2はStore2を使用しているため、クールではありません。

実際には、たとえば、Grid2の構成に追加することでハックできます。

store: new Model1().model2(),

ただし、ExtJSMVCパターンを使用している場合はどうなりますか。Grid2はModel1について何も知る必要はありません。

実際のプロジェクトで使用することはお勧めしません。associations少なくとも今は。代わりに、例に示されているアプローチを使用してください:モデル+ストア+フィルタリング。

于 2011-07-31T08:51:42.920 に答える
9

ExtJS 4 ではすべて正常に動作しますが、最初は正しく動作するのが難しいだけです。さて、最初の数回。

はい、子の属しているアソシエーションを指定することを避けて、それを Has Many リレーションシップで引き続き使用できます。

私のプロジェクトには、何十ものモデルがあり、その多くは深い関係にあり、うまく機能しています。

多対多の関係に関しては、次のいずれかが必要です

Customer -< CustomerOrder >- 注文

どれが3つのモデルで、

または、顧客が HasMany Orders を注文したふりをするために、サーバー上で一連の作業を行うことによって、それを「偽造」することもできます。ここでは、ネストされた json が役立ちます。

于 2012-05-24T20:01:42.010 に答える
3

私はモレキュラーマンに完全に同意します。ExtJS のドキュメントを読むと、さまざまなストアに分散されたツリー セット構造を利用している場合に、これが適切なルートであることが明らかになりました。率直に言って、これはすべて、そのような関連付けが何らかの形で電話をかけるための店舗の参照を持っている場合にのみ当てはまります. 私がテストしたものからはそうではありません。モデル協会にはそのような関係はありません。フィルタリングは、モデルが他のグリッドに依存する他のグリッドを順次更新するための最良の方法です。

于 2012-05-24T14:58:47.600 に答える
0

あなたの仮定に注意してください:

(顧客)1-n(注文)1-n(製品)

間違っている。実際のモデルは次のようになります。

(顧客)1-n(注文)n -n(製品)

そのため、hasMany-belongsToを使用してモデル化するのも困難であることがわかりました。

于 2013-01-23T08:44:29.093 に答える