2012-05-25 61 views
0

這個問題很難用文字來形容,所以讓我知道它是否需要澄清。 我對backbone.js很陌生,所以這可能是一個愚蠢的問題。如何強制Backbone.js不刪除'默認'值的兄弟姐妹?

我想使用主幹來輕鬆創建圖表(highcharts庫)。我想在模型中的默認對象中保留一個大型的json對象,其中包含所有常見的highcharts設置。然後,我要重寫一些變量,例如包含的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對象。除了我想要替換的值之外,如何讓它保存所有存儲的內容(backgroundColor等)?

在此先感謝 ķ

回答

2

一個非常簡單的方法,如果你有你的模型的平面表示,將沿着這些路線的東西,你可以定義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); 
    } 
}); 

我更喜歡的實現上面這個實施像這樣,因爲你沒有將自舉綁在一起,這可能實際上觸發不需要的事件:

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 
    }; 
}); 

但由於你有一個深度嵌套而不是模型的平面表示,您將不得不做一些額外的魔術來替換嵌套對象內的各個鍵/值對,如果您決定像上例中那樣擴展它,那麼您將覆蓋整個對象。

值得慶幸的是jQuery的extend方法,而不是underscore.js的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! 
    } 
}); 
+0

嗨。這一切似乎都很明智,但不幸的是'默認'對象是嵌套的。這一切都歸結於合併這樣的: '例1 = { P1: 'A', P2:{ 一個= 「一個」, B = 「兩節」 } } 本: 例題= { P2:{ 一個= 「別的東西」 } } 成這樣: 結果= { P1: 'A', P2:{ 一個= 「別的東西」, b =」兩個「 } }' – Klon

+0

更新我的答案,如何做deepmerge –

+0

太棒了,非常感謝! 不幸的是,它並沒有馬上工作 - 你的意思是發送屬性,而不是選項 - 即設置this.attrs = attr而不是this.options 非常感謝! – Klon

0

你可以使用初始化函數做一些自定義的數據處理。

myModel = Backbone.Model.extends({ 
initialize: function(myObject){ 
// do some stuff with myObject 
} 
});