在“同时”属性更改时渲染一次

时间:2013-08-08 22:36:06

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

在我的Backbone.js应用程序中,我有以下模型和视图:

var Operation = Backbone.Model.extend({

    defaults: function() {
        return {
            sign: '-',
            value: '0000',
            index: 0
        }
    }
});
var operation = new Operation();

var OperationView = Backbone.View.extend({

    el: '#operation',

    initialize: function() {
        this.listenTo(this.model, 'change:sign change:value', this.renderOperation);
        this.renderOperation();
    },

    renderOperation: function() {
        console.log('rendered once');
        this.$el.html(this.model.get('sign') + this.model.get('value'));
    }
});
var operationView = new OperationView({ model: operation });

视图的位置

'change:sign change:value'

(...每当“sign”或“value”发生变化时更新视图。)

当我使用

// Test
setInterval(function() {
    var newValue = parseInt(operation.get('value'), 10);
    newValue += 500;
    newValue += '';
    operation.set({ 'sign': '+', 'value': newValue });
}, 1000);

...第一次执行setInterval时,视图会更新两次(“渲染一次”是console.logged 2次)。

但是,由于我同时设置了符号和值,我宁愿我的视图只更新一次。

问题:在Backbone.js中,是否有任何方法可以在模型的多个(特定)属性中进行listenTo()更改,如果同时设置多个属性,则只渲染视图一次

1 个答案:

答案 0 :(得分:6)

您正在查看'change:sign change:value',

因此,当该属性发生变化时,事件会针对每个属性更改触发一次。

您始终可以在模型上收听change事件。如果在同一组哈希中更改了模型属性,则只会触发一个change

this.listenTo(this.model, 'change', this.renderOperation);

<强> Check Fiddle - Change Event

但是,如果您仍想在属性上侦听多个更改事件,并且只触发一次事件。在设置值和触发属性更改事件时,您可能会使用hack来传递{silent: true}。这有点蠢。

var Operation = Backbone.Model.extend({

    defaults: function () {
        return {
            sign: '-',
            value: '0000',
            index: 0
        }
    }
});
var operation = new Operation();

var OperationView = Backbone.View.extend({

    el: '#operation',

    initialize: function () {
        this.listenTo(this.model, 'change:sign change:value', this.renderOperation);
        this.renderOperation();
    },

    renderOperation: function () {
        console.log('rendered once');
        this.$el.html(this.model.get('sign') + this.model.get('value'));
    }
});
var operationView = new OperationView({
    model: operation
});

setInterval(function() {
    var newValue = parseInt(operation.get('value'), 10);
    newValue += 500;
    newValue += '';
    operation.set({ 'sign': '+', 'value': newValue }, {silent: true});
    operation.trigger('change:sign')
}, 1000);

<强> Suppress events and trigger Fiddle