5

ゴール

ArrayController(ArrayProxy)によって管理されるモデルの配列を作成します。要件

ArrayController(ArrayProxy)抽象化を使用して、ArrayProxyへの挿入時にArrayProxyに入力されたモデルのConvertオブジェクトの配列を自動的にカプセル化します。アクセス時に遅延変換しないでください。

データ構造の例

App.AddressModel = Ember.Object.extend({
    address_name: null,
    address: null,
    printme: function() {
        console.log("Just making sure the array turned into an AddressModel");
    },
});

App.addressArray = Ember.ArrayProxy.create({
    transformFrom: function(item) {
    },
    transformTo: function(item) {
    },
    arrayContentWillChange: function(startIdx, removeAmt, addAmt) {
    },
});

裁判による失敗

動的プロパティ

IRCチャネルの誰かが、動的プロパティの試行について言及しました。これは、論理的および経験的証拠によって見られたものである、再帰的な結果をもたらしました。動的に生成された変数と「トリガー/エクスポートされた」変数の両方のコンテンツを作成することは間違いありません。

arrayContentWillChange

繰り返しますが、一見再帰的な結果です。arrayContentWillChange通知を受信すると、指定された配列インデックスアイテムからAddressModelを生成します。次に、古いインデックス付きアイテムを作成されたモデルに設定すると、arrayContentWillChangeイベントが再度トリガーされ、…繰り返します。

transformFrom / transformTo

https://github.com/emberjs/ember.js/pull/554#issuecomment-5401112 tomdaleは、上記の投稿で、transformFromとtransformToを使用して着信データや発信データをキャストしようとしていると述べています。これらの関数は存在しないようです[http://cloud.github.com/downloads/emberjs/ember.js/ember-0.9.8.js]。

ArrayProxyモデルパッチ

https://github.com/emberjs/ember.js/pull/554 この問題の元の解決策/投稿に対するtomdaleの提案は、jedwoodによって導入されたモデルの実装よりも一般化されているようですが、Backbone.jsではこの問題を次のように処理します。特別なモデル変数を使用すると、うまく機能することがわかりました。

質問

ArrayProxyを拡張して、管理対象のすべての着信オブジェクトをAddressModelに変換するにはどうすればよいですか?

4

1 に答える 1

5

replaceメソッドを上書きするTom Daleが言及したアプローチを取りました。また、contentプロパティのオブザーバーを登録して、コンテンツが配列の型指定されたバージョンであることを保証します。 http://jsfiddle.net/pangratz666/XCLmE/を参照してください。

App.ModelArrayProxy = Ember.ArrayProxy.extend({
    modelType: Ember.required,

    _typedArray: function(objects) {
        var modelType = this.get('modelType');
        var array = objects.map(function(item) {
            // check if item is an instance of type
            if (!(item instanceof modelType)) {
                // create a new instance of type and pass the hash
                return modelType.create(item);
            }

            // just return the item, since it's already of type modelType             
            return item;
        });
        return array;
    },

    contentChanged: function() {
        if (!this.get('setTypedContent')) {
            var content = this.get('content');

            this.set('setTypedContent', true);
            this.set('content', this._typedArray(content));
            this.set('setTypedContent', false);
        }
    }.observes('content'),

    replace: function(idx, amt, objects) {
        this._super(idx, amt, this._typedArray(objects));
    }
});

この ModelArrayProxy は、「通常」として使用できますArrayProxy

// model declaration
App.AddressModel = Ember.Object.extend({
    ...
});

// create a proxy for given modelType
App.proxy = App.ModelArrayProxy.create({
    content: [],
    modelType: App.AddressModel
});

var myArray = [{
    address_name: 'address_name 1',
    address: 'address 1'},
{
    address_name: 'address_name 2',
    address: 'address 2'}];

// set content with "normal" objects
App.proxy.set('content', myArray);

// invoke 'log' on all items in array
App.proxy.forEach(function(item) {
    item.log();
});

// push a normal object
App.proxy.pushObject({
    address_name: 'address_name 3',
    address: 'address 3'
});

// push an instance of App.AddressModel
App.proxy.pushObject(App.AddressModel.create({
    address_name: 'address_name 4',
    address: 'address 4'

}));

// invoke 'log' on all items in array
App.proxy.forEach(function(item) {
    item.log();
});​
于 2012-05-24T19:22:43.620 に答える