Рендеринг один раз при одновременном изменении атрибута

В моем приложении 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'

(...обновление представления при изменении "знака" или "значения".)

Когда я использую

// 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 какой-либо способ прослушивания() изменений в нескольких (конкретных) атрибутах модели и рендеринга представления только один раз, если указанные несколько атрибутов установлены одновременно?


person Jackson    schedule 08.08.2013    source источник


Ответы (1)


Вы просматриваете, слушает оба 'change:sign change:value',

Таким образом, при изменении этого атрибута событие запускается один раз для каждого изменения атрибута.

Вы всегда можете прослушать событие change на модели. который вызовет только один change, если свойства модели будут изменены в том же заданном хэше.

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

Проверить скрипт — изменить событие

Но если вы все еще хотите прослушивать несколько событий изменения атрибутов, которые запускают событие только один раз. Вы можете прибегнуть к хаку, чтобы передать {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);

Подавлять события и запускать Fiddle

person Sushanth --    schedule 08.08.2013
comment
Спасибо за вашу помощь, но, к сожалению, это не ответ на мой вопрос. Я хочу прослушивать изменения в нескольких (конкретных) атрибутах модели. В вашем примере мое представление будет обновляться при изменении ЛЮБОГО атрибута, но я не хочу обновлять свое представление при изменении атрибута моего индекса. - person Jackson; 09.08.2013
comment
Вы всегда можете передать свойство silent:true всякий раз, когда вы устанавливаете индекс для модели. Таким образом, это не вызовет событие изменения. В противном случае вы можете выбрать вариант 2, который я предоставил, который запускает события после установки свойства, но прослушивает 'change:sign change:value', события изменения для определенных атрибутов. - person Sushanth --; 09.08.2013
comment
Ах я вижу. Хорошее редактирование, которое точно отвечает на мой вопрос. Решение не красивое, но этого следовало ожидать, учитывая довольно привередливый сценарий, который я создал. Большое спасибо! - person Jackson; 09.08.2013
comment
@ Джексон .. Рад, что помог :) - person Sushanth --; 09.08.2013