我遇到了非常不愉快的情况。
以下是模型初始化的代码:
var Model = Backbone.Model = function(attributes, options) {
var attrs = attributes || {};
options || (options = {});
this.cid = _.uniqueId('c');
this.attributes = {};
if (options.collection) this.collection = options.collection;
if (options.parse) attrs = this.parse(attrs, options) || {};
attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
this.set(attrs, options);
this.changed = {};
this.initialize.apply(this, arguments);
};
这里的问题是当模型在init上获取属性map时,如果属性已经存在则忽略默认值,并且在设置传递给构造函数的内容之前不会设置默认值。
逻辑上以为我会期望默认值始终在初始化时设置,然后在调用“set”方法时将替换值,这样我可以覆盖“set”方法来处理数组类型属性并将它们转换为像这样的集合:
set: function () {
var firstArgument = arguments[0],
attributesMap;
if (_.isObject(firstArgument)) {
//setting with attributes map
attributesMap = firstArgument;
_.each(attributesMap, function (value, attribute) {
var modelAttribute = this.attributes[attribute];
if (modelAttribute && modelAttribute instanceof Backbone.Collection) {
modelAttribute.reset(value);
delete attributesMap[attribute];
}
}, this);
}
return Backbone.Model.prototype.set.apply(this, arguments);
}
现在我正在做的是检查默认属性是否是Backbone.Collection的实例,如果是,我重置具有给定数组值的集合(保持相同的集合引用并允许视图或其他数据对象侦听该集合)并防止它被常规数组覆盖。
由于我之前在调用“set”方法时遇到的问题,它没有默认属性,我无法检查我想要操作的属性类型。
如何处理数组属性以及应该转换并作为Backbone.Collection处理的属性?
现在我只是改变了“默认”功能所做的事情而不是返回属性对象我这样做:
defaults: function () {
this.attributes = {
...
};
}
答案 0 :(得分:0)
这取自Backbone来源
var Model = Backbone.Model = function(attributes, options) {
var attrs = attributes || {};
options || (options = {});
this.cid = _.uniqueId('c');
this.attributes = {};
if (options.collection) this.collection = options.collection;
if (options.parse) attrs = this.parse(attrs, options) || {};
attrs = _.defaults({}, attrs, _.result(this, 'defaults')); // (1)
this.set(attrs, options);
this.changed = {};
this.initialize.apply(this, arguments);
};
正如您在(1)中看到的,它使用下划线默认值,它只是在调用set之前合并对象覆盖。
我想你的问题的解决方案可能是两次调用set,如下所示:
...
if (options.parse) attrs = this.parse(attrs, options) || {};
this.set( _.result(this, 'defaults') , options); // set the default attrs
this.changed = {};
this.set( _.defaults({}, attrs) , options); // set the attrs as passed in arguments
this.initialize.apply(this, arguments);
};
定义一个新模型并保持骨干源不受影响当然会更清晰。
虽然我可能猜到你想做什么,但我认为你应该考虑采用另一种方式。
我希望有所帮助!