监听嵌套模型属性的变化
Listen to changes from nested model attributes
我有一个模型属性,它是一个对象:
name : "testing",
orderCondition: {
minOrderAmount: 20,
deliveryCostRequire: "MIN_ORDER_AMOUNT",
deliveryCostAmount: 5.55
}
当我这样使用listenTo
时,render
函数没有被调用
this.listenTo(this.model, "change:orderCondition", this.render); // NO FIRING
但是当我在其他属性上使用 listenTo
时,它起作用了。
this.listenTo(this.model, "change:name", this.render); // FIRING
为什么 listenTo
看不到嵌套对象的变化但在简单属性中看到它们?
只是因为 Backbone 不适用于嵌套对象。例如,您不能通过 model.set()
.
set
对象 属性 的属性
您的 this.listenTo
只监听整个对象的变化,而不是它的属性。
您可以尝试使用 backbone-deep-model 等库来支持嵌套对象。
使嵌套对象属性触发 change
事件的一种简单方法是用新对象替换整个对象。最简单的方法是 set
:
model.set('orderCondition', _.extend({}, model.get('orderCondition'), {
deliveryCostRequire: "TOTAL_ORDER_AMOUNT"
}));
创建一个函数来设置模型的嵌套属性是封装这种复杂性的好方法。
var Model = Backbone.Model.extend({
setDeliveryCostRequire: function(value, options) {
// build a new object for 'orderCondition'
var newOrderCondition = _.extend({}, this.get('orderCondition'), {
deliveryCostRequire: value
});
// replace 'orderCondition' with the new object.
this.set({ orderCondition: newOrderCondition }, options);
// optionally trigger a custom event for it.
this.trigger('change:deliveryCostRequire', this, value, options);
return this;
},
});
这是基本概念。
Backbone.epoxy 是一个 two-way 绑定库,它还为模型提供计算字段,实现与上述相同的效果,但具有对模型外部完全透明的额外好处。
var Model = Backbone.Model.extend({
computeds: {
deliveryCostRequire: {
deps: ['orderCondition'],
get: function(orderCondition) {
return orderCondition && orderCondition.deliveryCostRequire;
},
set: function(value) {
return {
orderCondition: _.extend({}, this.get('orderCondition'), {
deliveryCostRequire: value
})
};
},
},
deliveryCostAmount: { /* ...other computed... */ },
}
});
使用此模型,您可以执行以下操作:
model.set('deliveryCostRequire', 'TOTAL_ORDER_AMOUNT');
model.get('deliveryCostRequire');
this.listenTo(model, 'change:deliveryCostRequire', this.render);
我也做了a simple way to bubble up events of nested models and collections.
我有一个模型属性,它是一个对象:
name : "testing",
orderCondition: {
minOrderAmount: 20,
deliveryCostRequire: "MIN_ORDER_AMOUNT",
deliveryCostAmount: 5.55
}
当我这样使用listenTo
时,render
函数没有被调用
this.listenTo(this.model, "change:orderCondition", this.render); // NO FIRING
但是当我在其他属性上使用 listenTo
时,它起作用了。
this.listenTo(this.model, "change:name", this.render); // FIRING
为什么 listenTo
看不到嵌套对象的变化但在简单属性中看到它们?
只是因为 Backbone 不适用于嵌套对象。例如,您不能通过 model.set()
.
set
对象 属性 的属性
您的 this.listenTo
只监听整个对象的变化,而不是它的属性。
您可以尝试使用 backbone-deep-model 等库来支持嵌套对象。
使嵌套对象属性触发 change
事件的一种简单方法是用新对象替换整个对象。最简单的方法是 set
:
model.set('orderCondition', _.extend({}, model.get('orderCondition'), {
deliveryCostRequire: "TOTAL_ORDER_AMOUNT"
}));
创建一个函数来设置模型的嵌套属性是封装这种复杂性的好方法。
var Model = Backbone.Model.extend({
setDeliveryCostRequire: function(value, options) {
// build a new object for 'orderCondition'
var newOrderCondition = _.extend({}, this.get('orderCondition'), {
deliveryCostRequire: value
});
// replace 'orderCondition' with the new object.
this.set({ orderCondition: newOrderCondition }, options);
// optionally trigger a custom event for it.
this.trigger('change:deliveryCostRequire', this, value, options);
return this;
},
});
这是基本概念。
Backbone.epoxy 是一个 two-way 绑定库,它还为模型提供计算字段,实现与上述相同的效果,但具有对模型外部完全透明的额外好处。
var Model = Backbone.Model.extend({
computeds: {
deliveryCostRequire: {
deps: ['orderCondition'],
get: function(orderCondition) {
return orderCondition && orderCondition.deliveryCostRequire;
},
set: function(value) {
return {
orderCondition: _.extend({}, this.get('orderCondition'), {
deliveryCostRequire: value
})
};
},
},
deliveryCostAmount: { /* ...other computed... */ },
}
});
使用此模型,您可以执行以下操作:
model.set('deliveryCostRequire', 'TOTAL_ORDER_AMOUNT');
model.get('deliveryCostRequire');
this.listenTo(model, 'change:deliveryCostRequire', this.render);
我也做了a simple way to bubble up events of nested models and collections.