目标
创建一个由ArrayController(ArrayProxy)管理的模型数组。
要求
使用ArrayController(ArrayProxy)抽象封装模型的数组
在插入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 channel 中有人提到尝试动态属性。从逻辑和经验证据看,这导致了递归结果。毫无疑问,既使内容成为动态生成的变量又使“触发/导出”变量成为可能。
arrayContentWillChange
同样,看似递归的结果。收到arrayContentWillChange通知后,我从给定的数组索引项生成了一个AddressModel。然后,将旧的索引项设置为创建的Model,并再次触发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中,使用特殊的model变量处理了这个问题,我发现它很好用。
问题
如何扩展ArrayProxy将所有要管理的传入对象转换为AddressModel?
最佳答案
我采用了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();
});
关于model - Ember.js ArrayProxy模型数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10743271/