javascript - 如何强制 Backbone.js 不删除 'default' 值的同级?

标签 javascript backbone.js

这个问题很难用语言描述,所以如果需要澄清的话请告诉我。 我对backbone.js很陌生,所以这可能是一个愚蠢的问题。

我想使用backbone来轻松创建图表(highcharts库)。我想在模型中的“默认”对象中保留一个包含所有常见 highcharts 设置的大型 json 对象。然后,我想重写一些变量,例如包含需要渲染图表的 dom 元素名称的变量。

这是我的代码:

var app = {
    Views:{},
    Models:{},
    Collections:{},
    init:function(){
        new app.Views.PageView();
    }
};

$().ready(_.bind(app.init,app));

 app.Models.chart = Backbone.Model.extend({
    defaults:{
        chart:{
           renderTo:'charts',
           backgroundColor:'#e1e1e1',
           height:200,
           width:200,
           defaultSeriesType:'spline',
           spacingRight:40,
           animation:false
        },
        colors:['#000', '#AA4643'],
        title:{
           text:''
        },
//lots lots lots of other attributes defined here.

app.Views.ChartView = Backbone.View.extend({
    render : function() {
        var chartContainer = this.model.attributes.chart.renderTo;
        $('#charts').append("<div id="+chartContainer+"></div>");

        new Highcharts.Chart(this.model.toJSON());
        return this;
    }
});

var chartDetails = [{chart:{renderTo:'div1'}},{chart:{renderTo:'div2'}}];

app.Views.PageView = Backbone.View.extend({
    el: $("#charts"),

    initialize : function(){
        this.chartCollection = new app.Collections.Charts(chartDetails);
        this.render();
    },

    render: function(){
        var that = this;
        _.each(this.chartCollection.models, function(item){
            that.renderChart(item);
        })
    },

    renderChart : function (item) {
        var chartView = new app.Views.ChartView({
            model: item
        });
        chartView.render();
    }
});

所以,这里真正的问题是:当我定义一个新集合时,我提供“chartDetails”对象,它会覆盖模型中指定的“默认”。因此,它不是更新 defaults.charts.renderTo 属性,而是替换完整的 defaults.charts 对象。除了我想要替换的值之外,如何让它保留存储在那里的所有内容(背景颜色等)?

提前致谢 k

最佳答案

一个非常简单的方法,如果您有模型的平面表示,那么您可以将 defaults 定义为函数

app.Models.Chart = Backbone.Model.extend(
{
    // we're using constructor to set this.options 
    //  as defaults gets called before initialize
    constructor: function (attrs, options)
    {
        this.attrs = attrs;
        Backbone.Model.prototype.constructor.apply(this, arguments)
    },
    // defaults can be defined as a function, yeah!
    defaults: function ()
    {
        var defaults = {
            renderTo: 'charts',
            backgroundColor: '#e1e1e1',
            height: 200,
            width: 200,
            defaultSeriesType: 'spline',
            spacingRight: 40,
            animation: false
        };
        return _.extend({}, defaults, this.attrs);
    }
});

与这样的实现相比,我更喜欢这种实现,因为您不会一次性将 Bootstrap 捆绑在一起,这实际上可能会触发不需要的事件:

app.Models.Chart = Backbone.Model.extend(
{
    initialize: function (attrs, options)
    {
        // this might trigger events, even if you make it {silent: true}
        // and is why I prefer the above implementation instead
        this.set(attrs); 
    },
    defaults: {
        renderTo: 'charts',
        backgroundColor: '#e1e1e1',
        height: 200,
        width: 200,
        defaultSeriesType: 'spline',
        spacingRight: 40,
        animation: false
    };
});

但是由于您的模型具有深度嵌套而不是平面表示,因此您将必须执行一些额外的操作来仅替换嵌套对象内的单个键/值对,因为如果您决定,您将覆盖整个对象如上例所示扩展它。

值得庆幸的是,与 underscore.js 的 extend 方法相反,jQuery 的 extend 方法为我们提供了一个 deep 参数,以便您可以执行以下操作:

app.Models.Chart = Backbone.Model.extend(
{
    // we're using constructor to set this.options 
    //  as defaults gets called before initialize
    constructor: function (attrs, options)
    {
        this.attrs = attrs;
        Backbone.Model.prototype.constructor.apply(this, arguments)
    },
    // defaults can be defined as a function, yeah!
    defaults: function ()
    {
        var defaults = {
            renderTo: 'charts',
            backgroundColor: '#e1e1e1',
            height: 200,
            width: 200,
            defaultSeriesType: 'spline',
            spacingRight: 40,
            animation: false
        };
        return $.extend(true, {}, defaults, this.attrs); // thank you jQuery!
    }
});

关于javascript - 如何强制 Backbone.js 不删除 'default' 值的同级?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10750968/

相关文章:

javascript - 位置固定的叠加不显示 div 内的所有内容

javascript - SCRAM 客户端 Javascript 实现/示例/库?

javascript - 如果我使用 Object.defineProperty() 定义 "name"属性,Error.prototype.toString() 将抛出 TypeError

javascript - 主干创建集合然后查看 - 异步?

jquery - 未捕获的 Backbone.localStorage : Environment does not support localStorage.

javascript - 使用 onClick 更新数据库

鼠标移动速度非常快时,Javascript 鼠标事件未正确捕获

backbone.js - 不推荐使用 Marionette 应用程序区域后的用途

javascript - Marionette 中布局内的布局

javascript - Backbone.js View 中的 this.el 究竟是什么?