これは私の最初の質問ですので、私はうんざりしていないことを願っています。 この問題について他のトピックを確認しましたが、私が抱えているケースをカバーしていません。バックボーン・ビューを拡張し、オプションを継承します。
モバイルアプリケーションを作成するためにBackboneの上にライブラリを構築しています。 バックボーンビューとしてすべてのコンポーネントを定義している主な理由は、スクロール(スムージング/ DOMからの削除)でメモリの最適化を行いたいからです。
私はちょうど最も理想的な状況になりdefenitionから始めましょう
は、いくつかのデフォルト プロパティと、私はすべてのコンポーネントに必要ないくつかの便利な方法で、使用する他のコンポーネントの基本クラスを定義します。
UI.Component = Backbone.View.extend({
viewOptions: ['children'],
children: [],
add: function(child) {
this.children.push(child);
}
});
実行してみましょう今私のナビゲーションバー
var homePageNavbar = new MyApp.Header.Default({
title: 'Homepage'
});
を使用して自分のアプリケーション
MyApp.Headers.Default = UI.Header.extend({
backButtonTitle: 'Terug',
titleBarChildren: [
new UI.SegmentedController({
children: [
new UI.Button('Lame example')
]
})
]
});
で使用するデフォルトのヘッダーを作るいくつかのデフォルトプロパティ
UI.Header = UI.Component.extend({
viewOptions: ['titleBarChildren', 'secondaryBarChildren', 'title', 'backButtonTitle'],
titleBarChildren: [],
secondaryBarChildren: [],
title: '',
backButtonTitle: 'Back'
});
でコンポーネントを定義します
そして、私たちは、私が最後に取得しようとしていた結果だ。この出力
// 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」アプローチでより多くの運を持って期待していますし、その後。好ましく、これは全てのUI.Componentで行うか、それは子供たちのさ_configure method
をオーバーライド。 私は、このライブラリのユーザーに、ヘッダーのdefenition(MyApp.Headers.Default = UI.Header.extend)に「定型コード」を追加して、オプションなどを拡張することは望ましくありません。
今や、私は何とかすべての "デセンダント"からすべての恩恵を得なければなりません。私はそれについてどうやって行くのか全く分かりません。 私は背骨の背後で何が起こっているのかを試してみましたが、私はその周りを頭で囲むことができません。
これを達成するためのヒント/トリックは非常に高く評価されています。また、私の正確な要件に合わない代替方法や方法も大歓迎です。
EDIT 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;
}
});
の最初の引数として、私は私のすべてのコンポーネントには、この新しいメソッドを追加した、と私はcouln以来、私のベースオブジェクト(UI.Component)で「共有」の性質を入れていません〜しないそれを素敵にすること。
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')
]
})
]
}
});
を定義するには、このようなものを使用し、私はそれにそれが今ある道を維持し、この「ソリューション」は存続かどうかを確認し、報告しますします。 あなたがより良い答えを持っていると思うなら、それを投稿しhestitateません=)
EDIT
これは、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);
動作するようです
私は間違いなくこれを再生して報告します。両方の「コンポーネント」にinitializeメソッドを追加する理由はありますか? UI.Componentがinitializeメソッドで自身を呼び出すのは正しいですか? (UI.Component.prototype.initialize.call(this、options);)無限ループにつながるのでは? – Vespakoen
ああ、そうです。最初のViewオブジェクトでは、Componentではなくinitializeメソッドを実行します。良いキャッチ、私はそれを更新しようとします。 –
これはありがとう、デフォルトの{}のアイデアを教えてくれてありがとう、本当に目が覚める。 私は3段階の拡張が必要なだけなので、私は "blockDefaults"と通常の "defaults"をビルドしていますが、それらのコンポーネントは自分のコンポーネントに "options"を設定してインスタンスを作成するときにオーバーライドすることができます。これまでのところ(私の最新の編集を見てください)。私はもう一晩寝るだろう。明日はそれについて考えるだろう=) – Vespakoen