0

我有显示对话框的简单视图。

Backbone.View.prototype.completeRemove = function(){
    this.undelegateEvents();
    this.remove();
    delete this.$el;
    delete this.el;
    console.log('completely removed')
}

MdApp.dialogBox = Backbone.View.extend({

    defaults: {
        text: __('No text provided'),
        buttonText: __('Ok'),
        callback: function(){
            return null;
        },
        el: $('#app-panel'),
        type: 'error',
        cancellable: false,
        cancelText: __('No'),
        picture: pic('default')
    },

    el: '<div class="dialog-box">',

    template: _.template($('#dialog-box-template').html()),

    events: {
        'click .confirm' : 'confirm',
        'click .cancel' : 'cancel'
    },

    initialize: function(){
        this.model = _.extend(this.defaults, this.model);
        this.render();
    },

    render: function(){
        var model = this.model;
        this.$el.html(this.template(model));
        model.el.append(this.el);
    },

    confirm: function(){
        var model = this.model;
        var view = this;
        this.completeRemove();
        model.callback();
    },

    cancel: function(){
        this.completeRemove();
    }
});

它有自己的默认值。每次我初始化新对话框时,它的值都会在每个对话框调用之间保持不变。例如,当我第一次调用对话框时:

new MdApp.dialogBox({model:{
        text: __('Do you really wanna delete this?'),
        buttonText: __('Unfortunately yes'),
        callback: function(){
            //some callback
        },
        cancellable: true,
        cancelText: __('No'),
        picture: pic('confirm delete')
    }});

之后,我将调用另一个没有cancellable属性的对话框,因此它应该使用默认对话框(即false),但它保持不变。这适用于所有其他财产。为什么会这样?

4

1 回答 1

2

来自精美手册

延长 _.extend(destination, *sources)

将源对象中的所有属性复制到目标对象,然后返回目标对象。

这意味着_.extend(o, ...)修改o. 所以当你这样做时:

this.model = _.extend(this.defaults, this.model);

您正在有效地执行此操作:

for(k in this.model)
    this.defaults[k] = this.model[k];
this.model = this.defaults;

附加到原型上,因此defaults实际上您正在更改defaults将由每个实例共享的MdApp.dialogBox. 这就是为什么你最终会得到粘性属性:你将所有不同this.model的 s合并到defaults视图原型上。

你可以这样做:

// Merge into an empty object to avoid altering this.defaults
this.model = _.extend({}, this.defaults, this.model);

或者你可以使用_.defaults而不是_.extend

默认值 _.defaults(object, *defaults)

默认对象中的值填充对象中的空和未定义属性并返回对象。一旦属性被填充,进一步的默认值将无效。

所以你可以这样做:

_(this.model).defaults(this.defaults);

这将this.model就地改变,因此您的视图将假设它完全拥有this.model并且没有对该对象的任何外部引用。

于 2013-05-16T18:30:25.570 回答