Backbone.js 你怎么样';改变';主干模型中处理的事件?
我试图构建一个模型,动态更新Meteor项目中的会话变量。我知道普通JSON不应该存储在主干模型中,所以我有一个特殊的模型,如下所示:Backbone.js 你怎么样';改变';主干模型中处理的事件?,backbone.js,model,meteor,Backbone.js,Model,Meteor,我试图构建一个模型,动态更新Meteor项目中的会话变量。我知道普通JSON不应该存储在主干模型中,所以我有一个特殊的模型,如下所示: initialize : function () { // Log the changed properties this.on('change', function (model, options) { for ( var i in options.changes) this.display(i);
initialize : function () {
// Log the changed properties
this.on('change', function (model, options) {
for ( var i in options.changes)
this.display(i);
Session.set('NewSpecial', model);
});
},
//Attributes
defaults: {
"Product" : null,
"ShortDescription" : null,
"Category" : "food",
"Price" : new PriceModel,
"Date" : new DateModel,
"Uses" : 0,
"Tags" : [],
"Contributor" : null
},
“价格”和“日期”存储在各自的型号中:
//Price model for use within Special
var PriceModel = Backbone.Model.extend({
defaults : {
"Regular" : null,
"Special" : null,
"PercentOff" : null
}
});
//Date model for use within Special
var DateModel = Backbone.Model.extend({
defaults : {
"StartTime" : null,
"EndTime" : null,
"HumanTimeRange" : null
}
});
如图所示,当特殊模型的属性更改时,它应该为更改的属性调用display,然后将会话变量设置为该模型。但是,如果我的DateModel或PriceModel发生更改,它似乎不会触发特殊模型上的更改事件。每个“DateModel”和“PriceModel”是否应该有自己的
this.on('change',…)
方法来调用Special.set(attribute,thisModel)
方法?还是有不同的方法来解决这个问题?我发现了几个问题
首先,您的默认值是:
defaults: {
"Product" : null,
"ShortDescription" : null,
"Category" : "food",
"Price" : new PriceModel,
"Date" : new DateModel,
"Uses" : 0,
"Tags" : [],
"Contributor" : null
}
defaults: function() {
return {
"Product" : null,
"ShortDescription" : null,
"Category" : "food",
"Price" : new PriceModel,
"Date" : new DateModel,
"Uses" : 0,
"Tags" : [],
"Contributor" : null
};
}
这将导致该模型的所有实例共享一个PriceModel
、一个DateModel
、一个标签数组。对象被浅层复制并合并到模型的属性中,默认值中的任何值都不会被克隆或复制,它们只是按原样复制。如果您想要区分价格
、日期
和标签
值,请使用默认值
函数:
defaults: {
"Product" : null,
"ShortDescription" : null,
"Category" : "food",
"Price" : new PriceModel,
"Date" : new DateModel,
"Uses" : 0,
"Tags" : [],
"Contributor" : null
}
defaults: function() {
return {
"Product" : null,
"ShortDescription" : null,
"Category" : "food",
"Price" : new PriceModel,
"Date" : new DateModel,
"Uses" : 0,
"Tags" : [],
"Contributor" : null
};
}
第二个问题是,人们对变化的含义有着相当简单的看法。如果您查看,您将看到:
// If the new and previous value differ, record the change. If not,
// then remove changes for this attribute.
if (!_.isEqual(prev[attr], val) || (_.has(now, attr) !== _.has(prev, attr))) {
this.changed[attr] = val;
if (!silent) this._pending[attr] = true;
} else {
delete this.changed[attr];
delete this._pending[attr];
if (!changing) delete this._changes[attr];
}
无法识别您的价格
或日期
中发生了更改,或者您从标签
中添加或删除了某些内容。如果你这样做:
p = new PriceModel(...);
m.set('Price', p)
initialize: function() {
this.attributes.Price.on(
'all',
function(ev, model, opts) { this.trigger(ev, model, opts) },
this
);
//...
}
然后m
会注意到Price
已更改,但如果您:
p = m.get('Price');
p.set(...);
m.set('Price', p);
然后m
将不会识别Price
已更改;您的模型不会自动绑定到Price
上的事件,因此它不会注意到p.set(…)
调用,也不会将m.set('Price',p)
识别为更改,因为这只不过是一种花哨的说法p=p
您可以通过不给set
一个来自get
的Tags
数组来解决部分更改问题;制作一份副本,更改副本,然后将更新后的副本交给set
。这一半可以通过绑定到包含的Price
和Date
模型上的“change”
事件来处理,并将其转发到类似于collections的方式,如下所示:
p = new PriceModel(...);
m.set('Price', p)
initialize: function() {
this.attributes.Price.on(
'all',
function(ev, model, opts) { this.trigger(ev, model, opts) },
this
);
//...
}
您希望提供自己的集
实现,以防有人做了集('Price',一些新对象)
,您需要重新绑定转发器