這是我的第一個問題,所以我希望我不會搞砸。 我已經檢查過有關這個問題的其他主題,但他們沒有涵蓋我遇到的情況。以乾淨的方式擴展骨幹視圖和繼承選項
我正在Backbone之上建立一個庫來創建移動應用程序。 我將所有組件定義爲骨幹視圖的主要原因是因爲我想在滾動(隱藏東西/從DOM中移除東西)上進行內存優化。
讓我開始用defenition那將是最理想的情況
定義一個基類的其他組件使用,一些默認 屬性和我需要的每個組件上一些方便的方法。
UI.Component = Backbone.View.extend({
viewOptions: ['children'],
children: [],
add: function(child) {
this.children.push(child);
}
});
定義組件的一些默認屬性
UI.Header = UI.Component.extend({
viewOptions: ['titleBarChildren', 'secondaryBarChildren', 'title', 'backButtonTitle'],
titleBarChildren: [],
secondaryBarChildren: [],
title: '',
backButtonTitle: 'Back'
});
製作一個默認的頭在我的應用程序
MyApp.Headers.Default = UI.Header.extend({
backButtonTitle: 'Terug',
titleBarChildren: [
new UI.SegmentedController({
children: [
new UI.Button('Lame example')
]
})
]
});
使用使用我的導航欄
var homePageNavbar = new MyApp.Header.Default({
title: 'Homepage'
});
現在讓我們運行
而且想象我們得到如下的輸出
// My properties, all nicely inherited
viewOptions: Array[5] //['children', 'titleBarChildren', 'secondaryBarChildren', 'title', 'backButtonTitle']
children: Array[0],
titleBarChildren: Array[1],
secondaryBarChildren: Array[0],
title: "Homepage",
backButtonTitle: "Terug"
// Some stuff that backbone assigns
$el: jQuery.fn.jQuery.init[1]
cid: "view12"
el: HTMLDivElement
options: Object
__proto__: ctor
這就是我想在最後得到的結果,然而,這需要一些魔術已經超出我的經驗。
在一個側面說明,我已經嘗試使用「選項」屬性爲我所有的自定義的東西,但問題是,當我創建多個視圖實例,選項是「共享」/引用彼此。
所以,現在我希望我將有更多的運氣與「viewOptions」的方法,然後重寫_configure method
Preferrably這是所有在UI.Component完成或它的孩子。 我不希望這個庫的用戶在標題defenition(MyApp.Headers.Default = UI.Header.extend)中添加一些「樣板代碼」來擴展選項或其他內容。
現在我不知何故必須從所有「後代」中取得所有的特性。我完全不知道如何去做。 我嘗試了以下在骨幹幕後發生的事情,但是我無法用頭包裹它。
因此,非常歡迎所有關於完成此操作的提示/技巧,以及其他替代方法或與我的確切要求不符的方法。
編輯1
它看起來像我有東西「之類的」作品,這裏是什麼樣子
我重寫_configure方法,將選項添加到該實例,請注意this.getDefaultOptions()作爲在_.extend第一個參數
UI.Component = Backbone.View.extend({
_configure: function(options) {
var viewOptions = this.viewOptions;
options = _.extend(this.getDefaultOptions ? this.getDefaultOptions() : {}, this.options || {}, options || {});
for (var i = 0, l = viewOptions.length; i < l; i++) {
var attr = viewOptions[i];
if (options[attr]) this[attr] = options[attr];
}
this.options = options;
}
});
我添加到我的所有組件這種新方法,並沒有把「共享」屬性在我的基礎對象(UI.Component),因爲我couln 「T把它打好。
UI.Header = UI.Component.extend({
viewOptions: ['children', 'backButtonTitle', 'title'],
getDefaultOptions: function() {
return {
children: []
};
},
});
現在,我使用這樣的定義我的頭
MyApp.Headers.Default = UI.Header.extend({
options: {
backButtonTitle: 'Terug',
titleBarChildren: [
new UI.SegmentedController({
children: [
new UI.Button('Lame example')
]
})
]
}
});
我會保持它現在是這樣的,看看這個「解決方案」生存,並會報到。 如果你認爲你有一個更好的答案,毫不猶豫將它張貼=)
編輯
這是我最新的方法,使用jQuery的深層副本,它似乎還好吧工作
var UI = {};
var App = {
Headers: {}
};
UI.Component = Backbone.View.extend({
blockDefaults: {
children: []
},
initialize: function(options) {
var combinedDefaultsAndOptions = $.extend(true, {}, this.blockDefaults || {}, this.defaults || {}, this.options || {}, options || {});
_.defaults(this, combinedDefaultsAndOptions);
}
});
UI.Header = UI.Component.extend({
defaults: {
backButton: null,
backButtonTitle: null,
secondaryBarChildren: []
}
});
App.Headers.Default = UI.Header.extend({
options: {
backButtonTitle: "App back",
secondaryBarChildren: ["App child"]
}
});
var header1 = new UI.Header({
backButtonTitle: "Header 1 Back",
secondaryBarChildren: ["Header 1 child"]
});
var header2 = new UI.Header({
backButtonTitle: "Header 2 Back",
secondaryBarChildren: ["Header 2 child"]
});
var header3 = new App.Headers.Default({
});
var header4 = new App.Headers.Default({
backButtonTitle: "Overrided App Back"
});
header1.secondaryBarChildren.push('a child for header 1');
console.log(header1, header2, header3, header4);
感謝您參與此次活動,我肯定會玩這個並報告回來,那麼在兩個「組件」中添加初始化方法的原因是什麼?並且,UI.Component在初始化方法中調用自身是否正確? (UI.Component.prototype.initialize.call(此,選項);)Wouln't導致無限循環? – Vespakoen
哦,對。在第一個View對象中,你需要運行它的initialize方法,而不是Component。很好,我會嘗試更新它。 –
感謝您的,感謝您給我看的默認值:{}想法,它是一個真正的大開眼界。 由於我只需要3個級別的擴展,我建立了一個「blockDefaults」和普通的「默認值」,除此之外,可以在我的組件上設置「選項」,並在製作實例時覆蓋它們,我對它很滿意到目前爲止(請參閱我的最新編輯)。我會再睡一晚,明天我會看到我的想法=) – Vespakoen