【问题标题】:Ember.js ArrayProxy Array of ModelsEmber.js ArrayProxy 模型数组
【发布时间】:2012-05-31 09:04:50
【问题描述】:

目标

创建由 ArrayController (ArrayProxy) 管理的模型数组。 要求

使用ArrayController(ArrayProxy)抽象封装Model的数组 在插入 ArrayProxy 时自动将对象输入转换为 ArrayProxy 访问时不要懒惰转换

示例数据结构

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?

【问题讨论】:

    标签: model ember.js


    【解决方案1】:

    我采用了 Tom Dale 提到的方法,它覆盖了 replace 方法。它还为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();
    });​
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    • 2013-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多