对于我的一个项目,我正在监听模型对象的属性变化,并在其属性发生变化时调用 View 方法。
问题是我的模型的属性之一是 momentjs 日期对象。
我查看了 Backbone 源代码,它似乎使用下划线方法 _.isEqual()
触发了 setter 中的更改。
看完underscore documentation , isEqual
对两个对象进行深度比较。
看起来不错,但是 momentjs 对象包含初始格式信息,即使日期的实际值具有相同的含义,如果它来自不同的地方,它可能会被格式化不同,因此,被下划线深度比较认为不相等.
// initialize model
var today = moment().startOf('day');
var model = new Backbone.Model({
start: today
});
// change event
model.on('change', function(e){
// if property start has changed
if(e.changed.hasOwnProperty('start')){
// log it
console.log('date changed');
}
});
// simulates input from user
var userInput = moment().startOf('day').format('DD/MM/YYYY');
model.set({
// it's the same day as today and it shouldn't trigger a change !
start: moment(userInput,'DD/MM/YYYY')
});
我该怎么办?
- 在我的模型中存储 unix 时间戳而不是 momentjs 对象?这也意味着重构我的整个代码...
- 找到一种方法来“覆盖”
isEqual
当它是一个 momentjs 对象时?但我宁愿不修改下划线,修改 momentjs 似乎还可以。
最佳答案
您最好的选择可能是覆盖 model.set
方法以对某些属性执行自定义相等性检查。
让我们创建 EqualModels
作为包含覆盖的基类:
var EqualModels = Backbone.Model.extend({
set: function(key, val, options) {
if (!this.equals)
return Backbone.Model.prototype.set.apply(this, arguments);
//lifted from Backbone source code
var attrs, attr, dropped, fn;
if (key == null) return this;
// Handle both `"key", value` and `{key: value}` -style arguments.
if (typeof key === 'object') {
attrs = key;
options = val;
} else {
(attrs = {})[key] = val;
}
options || (options = {});
//determine which attributes have a custom equality check and apply it
dropped = [];
for (attr in attrs) {
fn = this.equals[attr];
if (_.isFunction(fn)) {
if (fn(this.attributes[attr], attrs[attr]))
dropped.push(attr);
}
}
//remove the attributes that are deemed equal
attrs = _.omit(attrs, dropped);
return Backbone.Model.prototype.set.call(this, attrs, options);
}
});
目标是确定属性是否具有 this.equals
中定义的相等性检查,将此函数应用于当前值和潜在值,如果值被认为是,则从集合属性中删除该属性相等。
然后你可以把你的模型写成
var M = EqualModels.extend({
equals: {
start: function(v1, v2) {
if (typeof(v1)!==typeof(v2)) return false;
return v1.format('DD/MM/YYYY')===v2.format('DD/MM/YYYY');
}
}
});
这里的 moment 对象仅在 DD/MM/YYYY 格式不同时更新。和一个演示 http://jsfiddle.net/Nwdf4/3/
关于javascript - 在 momentjs 对象上更改事件触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20352846/