0

我遇到了非常不愉快的情况。

这是模型初始化的代码:

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 上获取属性映射时,如果属性已经存在,它会忽略默认值,并且在设置传递给构造函数的内容之前不会设置默认值。

逻辑上认为我希望总是在初始化的一开始就设置默认值,然后在调用“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 = {
        ...
    };
}
4

1 回答 1

0

这取自骨干资源

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

当然,定义一个新模型并保持主干源不变会更干净。

此外,虽然我可能猜到你想做什么,但我认为你应该考虑另一种方法。

我希望有帮助!

于 2013-11-14T20:29:02.390 回答