2012-11-20 15 views
6

これは私の最初の質問ですので、私はうんざりしていないことを願っています。 この問題について他のトピックを確認しましたが、私が抱えているケースをカバーしていません。バックボーン・ビューを拡張し、オプションを継承します。

モバイルアプリケーションを作成するために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); 
動作するようです

答えて

1

あなたの例では初期化関数をオーバーライドしたいと思いますが、あなたは多くのことが起こっているのでわかりません。これがオフの場合、私を許してください。そして私はあなたがもっと「バックボーン」スタイルのシステムにしようとしていると思っているものを掃除するかもしれません。

このようなあなたの基本コンポーネントでスタート:

UI.Component = Backbone.View.extend({ 
    defaults : { 'children' : [] }, 
    initialize : function (options) { 
     _.defaults(options, this.defaults); 
     _.keys(this.defaults).forEach(function(key) { 
       this[key] = this.options[key]; 
     }.bind(this)); 
     Backbone.View.prototype.initialize.call(this, options); 
    }, 
    add: function(child) { 
     this.children.push(child); 
    } 
}); 

次に、あなたがこのような同様の方法でそれらを拡張し続けることができます。

UI.Header = UI.Component.extend({ 
    defaults : { 
     'titleBarChildren' : [], 
     'secondaryBarChildren' : [], 
     'title' : '', 
     'backButtonTitle' : 'Back' 
    }, 
    initialize : function (options) { 
     _.defaults(options, this.defaults); 
     _.keys(this.defaults).forEach(function(key) { 
       this[key] = this.options[key]; 
     }.bind(this)); 
     UI.Component.prototype.initialize.call(this, options); 
    } 
}); 

ここで私がしようとしているものの内訳は、ですコード内で行う:

デフォルトはすべてのデフォルト属性をきれいに保持するオブジェクトを作成します

defaults : { 'children' : [] }, 

初期オーバーライドを使用すると、表示するビューからオプションを渡し続けることができますが、各コンポーネントは、ギャップを埋めるためにあなたのdefaultsオブジェクトを使用しています。

+0

私は間違いなくこれを再生して報告します。両方の「コンポーネント」にinitializeメソッドを追加する理由はありますか? UI.Componentがinitializeメソッドで自身を呼び出すのは正しいですか? (UI.Component.prototype.initialize.call(this、options);)無限ループにつながるのでは? – Vespakoen

+0

ああ、そうです。最初のViewオブジェクトでは、Componentではなくinitializeメソッドを実行します。良いキャッチ、私はそれを更新しようとします。 –

+0

これはありがとう、デフォルトの{}のアイデアを教えてくれてありがとう、本当に目が覚める。 私は3段階の拡張が必要な​​だけなので、私は "blockDefaults"と通常の "defaults"をビルドしていますが、それらのコンポーネントは自分のコンポーネントに "options"を設定してインスタンスを作成するときにオーバーライドすることができます。これまでのところ(私の最新の編集を見てください)。私はもう一晩寝るだろう。明日はそれについて考えるだろう=) – Vespakoen

関連する問題