从嵌套模型属性中聆听更改

时间:2017-01-17 09:33:55

标签: javascript backbone.js backbone-views backbone-events

我有一个模型属性,它是一个对象:

$cause_tags

当我像这样使用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 看不到嵌套对象的变化,但是在简单的属性中看到它们?

2 个答案:

答案 0 :(得分:2)

使嵌套对象属性触发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是一个双向绑定库,它还为模型提供了与上述相同的计算字段,但还具有从模型外部完全透明的额外好处。

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

答案 1 :(得分:0)

仅仅因为Backbone不能与嵌套对象一起使用。例如,您不能通过set model.set() this.listenTo对象属性的属性。

你的{{1}}只是在听整个对象的变化,而不是它的属性。

您可以尝试使用backbone-deep-model等库来嵌套对象支持。