2012-05-22 3 views
5

これで、ナビゲーションとダッシュボードの概念が得られました。ルーターでナビゲーションリンクをクリックすると、アクティブなタブを設定するためにダッシュボードビューが呼び出されます。例えば1つのdivを複数のバックボーン・ビューのコンテナとして使用してイベント・バインディングを失う

NAV

<a href="#" class="dashabord_tab" id="widgets">Widgets</a> 
<a href="#" class="dashabord_tab" id="Foobars">Foobars</a> 

dashboard_container.jst.tpl

<div id="nav"></div> 
<div id="current_tab"></div> 

DASHABORDVIEW

DashboardView = Backbone.View.extend({ 
    template:JST.dashboard_container, 
    render: function(){ 
    $(this.el).html(this.template()); 
    }, 
    activateWidgets: function(){ 
    if(!(this.widgets_view)){ 
     this.widgets_view = new WidgetsView(); 
     this.widgets_view.render(); 
    } 
    $(this.el).find("#current_tab").html(this.widgets_view.el); 
    }, 
    activateFoobars: function(){ 
    if(!(this.foobars_view)){ 
     this.foobars_view = new FooBarsView(); 
     this.foobars_view.render(); 
    } 
    $(this.el).find("#current_tab").html(this.foobars_view.el); 
    } 
}); 

問題:

初めてwidgets_tabまたはfoobar_tabに切り替えると、タブが期待通りに読み込まれます。しかし、私はタブに切り替える場合は、それから切り替え、それに戻ってスイッチ、私のビュー内のすべてのイベントはもはやバインドされていません。 、

過去のソリューション:クリックすると、hoevering、例えばfoobars_view内部の意見のどれもが、私は、各そうのような子ビューのいずれかのラッパーを作っている、など過去に

、hoverable、クリック可能ではありませんピタパン:

activateFoobars: function(){ 
    $('.tab_wrapper').hide(); 
    if($(this.el).find("#foobars_wrapper").length < 1){ 
     $(this.el).append("<div class='tab_wrapper' id='foobars_wrapper'></div>"); 
     this.foobars_view = new FooBarsView(); 
     $(this.el).find("#foobars_wrapper").html(this.foobars_view.render().el); 
    } 
    $('#foobars_wrapper').show(); 
    } 

私はむしろそれを私は「できれば私はちょうど...上記示した、と私は本当にただ常に開いたままactive_tab divの中でビューのエルを置くという考えのようなやり方はしないだろう私がしたいと思うようにしてください、私はちょうど上に示した方法の代替ですか?ありがとう!

答えて

5

あなたは.html(dom_object)使用する場合:

$(this.el).find('#current_tab').empty().append(this.widgets_view.el); 

empty

は、このようなデータやイベントハンドラなどの他の構成要素を削除し

$(this.el).find("#current_tab").html(this.widgets_view.el); 

は、あなたが実際にこれをやっています子要素を削除する前に子要素を削除する[メモリリークを防ぐ]

あなたは、たとえば、#current_tabからを添加し、次いで.html(this.foobars_view.el)したらそう、widgets_view.elのイベントがなくなっています。 .htmlコールは、には何もないので、最初は正常に動作します。したがって、バインドを解除するイベントはありません。

あなたがイベントを再バインドするためにミックスに簡単なdelegateEvents呼び出しを追加することによって、あなたの「ビューを再利用」のアプローチを使用することができます。

activateWidgets: function(){ 
    if(!(this.widgets_view)){ 
    this.widgets_view = new WidgetsView(); 
    this.widgets_view.render(); 
    } 
    $(this.el).find("#current_tab").html(this.widgets_view.el); 
    this.widgets_view.delegateEvents(); // <--------------- you need this 
} 

私がここにいる間、あなたの代わりにthis.$('#current_tab')代わりの$(this.el).find('#current_tab')this.$elを使用することができます$(this.el)です。

デモ:上記のタブを切り替えること<input type="text">要素の内容を保存することhttp://jsfiddle.net/ambiguous/75KuW/1/

注意。そのような振る舞いが必要ない場合は、すべてのビューを保持したり入れ替えるのではなく、必要に応じてビューを削除してインスタンス化するほうがよいでしょう。

また、あなたのWidgetsView(およびその友人)が他のバックボーンビューを持っている場合は、含まれているビューの全部をダウンしてdelegateEventsと呼ぶ必要があります。何らかの理由で、それは私のアプリケーションで作業していないです...あなたのjsfiddle例では素晴らしい作品

this.widgets_view.rebind_events(); // delegateEvents() all the way down this view subtree 
+0

:この場合、ビュー上のbind_events方法のいくつかの並べ替えは、理にかなって。私は、widgetsviewとfoobarviewの両方が独自の子ビューを持っていることに注意してください。違いがありますか? – jdkealy

+0

@ jdkealy: 'empty'呼び出しが** all **イベントバインディングを殺してしまうので、おそらく' delegateEvents'をすべて終了させる必要があります。必要な 'delegateEvents'を行うビューのメソッド(例えば' rebind_all_events')は、物事を適切にカプセル化しておくことを意味します。 –

+0

ああ、私が今見ているのは、単純な見方をするとうまくいきます。そうですね、私の見解はあまりにも深く行きます。私はdelegateEventsをチェーンのすべてのところで呼び出すと思います。これは将来の参照のために知っておくと良いですが、私はshow/hideメソッドまたはoffsetメソッドを使うつもりだと思います。ありがとう! – jdkealy

関連する問題