7

私の髪の毛を引っ張っていますが、私が最もばかげたことをしない限り、ビューが再レンダリングされた後、バックボーン・ビュー・イベントは再レンダリング後には機能しません

$("a").die().unbind().live("mousedown",this.switchtabs); 

私は実際にそこでこれを持っていたが、最新のバックボーンに更新し、新しいdelegateEvents()機能を使用しようとすることを決めました。

何が起こることはtabcollectionは、すべてのタブを管理するためのメインtabviewを持っていることである
Appview/AppRouter 
    | 
    ----->PageCollection 
      | 
      ------->PageView/PageModel 
      ------->PageView/PageModel  these page view/models are not rendered 
      ------->PageView/PageModel 
      | 
      ------->PageView/PageModel 
         | 
         ----->render()  *when a pageview is rendered* 
           | 
           -----> Creates new 
            Tabcollection 
             | 
             --->TabModel/TabView <-- this is where the issue is 

が、その後、各タブの新しいモデル/ビューを作成します:ここで

は私のプロジェクトIDが構造化された方法でありますリスナーを使用して、タブがロードされるたびにタブビューを再描画します。タブビューが再レンダリングされた場合、そこに作成されたjQueryステートメントを置かない限り、マウスイベントはもう機能しません。彼らはDOMではないので

相続人tabviewとレンダリング(かなりそれをストリップダウンアイブ)

var TabPanelView = Backbone.View.extend({ 
    className:  "tabpanel", 
    html:   'no content', 
    model:   null, 
    rendered:  false, 
    events:{ 
     'click a.tab-nav': 'switchtabs' 
    }, 
    initialize: function(args) 
    { 
     this.nav   = $("<ol/>"); 
     this.views   = args.items; 
     this.className  = args.classname?args.classname:"tabpanel"; 
     this.id    = args.id; 
     this.container  = $("<section>").attr("class",this.className).attr("id",this.id); 
     _.bindAll(this); 
     return this.el 
    }, 
    /* 
    This render happens multiple times, the first time it just puts an empty html structure in place 
    waiting for each of the sub models/views to load in (one per tab) 
    */ 
    render: function(args){ 
     if(!args) 
     { 
      //first render 
      var nav    = $("<aside/>").addClass("tab-navigation").append("<ol/>").attr("role","navigation"); 
      var tabcontent  = $("<section/>").addClass("tab-panels"); 
      for(i = 0;i<this.views.length;i++) 
      { 
       $("ol",nav).append("<li><a rel='"+this.views[i].id+"' href='javascript:;' class='tab-nav'></a></li>"); 
       tabcontent.append(this.views[i].el); 
      } 
      this.$el.empty().append(nav).append(tabcontent); 
     } 
     else if(args && args.update == true){ 
      // partial render -- i.e. update happened inside of child objects 
      var targetid = args.what.cid; 
      for(i = 0;i<this.views.length;i++) 
      { 
       var curcontent = this.$el.find("div#"+this.views[i].id); 
       var curlink  = this.$el.find("a[rel='"+this.views[i].id+"']") 
       if(this.views[i].cid == targetid) 
       { 
        curcontent.html($(this.views[i].el).html()); 
        curlink.text(this.views[i].model.rawdata.header); 
       } 
       if(i>0) 
       { 
        // set the first panel 
        curcontent.addClass("tab-content-hide"); 
       } 
       if(i==0) 
       { 
        curcontent.addClass("tab-content-show"); 
        curlink.addClass("tab-nav-selected"); 
       } 
       // this ridiculous piece of jQuery is the *ONLY* this i've found that works 
       //$("a[rel='"+this.views[i].id+"']").die().unbind().live("mousedown",this.switchtabs); 
      } 
     } 
     this.delegateEvents(); 
     return this; 
    }, 
    switchtabs: function(args){ 

     var tabTarget = args.target?args.target:false 
     if(tabTarget) 
     { 
      this.$el.find("aside.tab-navigation a").each(function(a,b) 
      { 
       $(this).removeClass("tab-nav-selected") 
      }) 
      $(tabTarget).addClass("tab-nav-selected"); 
      this.$el.find("div.tab-content-show").removeClass("tab-content-show").addClass("tab-content-hide"); 
      this.$el.find("div#"+tabTarget.rel).removeClass("tab-content-hide").addClass("tab-content-show"); 
     } 
    } 
}); 

は、誰もがバックボーンマウスイベントは、単にすべてで解雇しない理由を考えることができ、それがあります?私はこれがバックボーンが特に有用だった場所だと思ったのですが... ...

+0

これまでのトラブルシューティングの手順を教えてください。私が試してみたいことのいくつか: 'events'要素が処理されるバックボーンソースにブレークポイントを設定できるかどうかを見てください。あなたにいくつかの洞察力を与えるかもしれません。また、ChromeのDOMおよびイベントリスナーのブレークポイントを使用してみてください。これは、コードがまったく実行されているかどうか、またはイベントがワイヤリングアップしていないかどうかを確認するのに役立ちます。 –

+0

Iveはjq $(document).find( "tab-nav-selected")に対してログを取って、レンダリングされた項目が実際にdomにあるかどうかを確認します。私自身のコードでブレークポイントを通過しました。デバッガでバックボーン自体を掘り起こすのに十分な自信がありません。スコープはすべてうまく見えます...私は確信はしていませんが、イベントは再レンダリングのために上書きされているかのように見えます... ummm – Alex

答えて

6

このコード行は、おそらくあなたの問題であるレンダリング:

this.delegateEvents();

これを削除すれば正常に動作します。

自分でdelegateEventsに電話する必要があるのは、ビューのeventsハッシュとは別に宣言されたイベントがある場合です。バックボーンのビューは、ビューのインスタンスを作成するときにこのメソッドを呼び出します。 $(el).empty()を使用している場合

+0

悲しいことにサイコロはありません。私はあなたのブログに有用なバックボーンのものをたくさん読んだことがあります。私は与えて、jQuery.liveと一緒に行った...はい、それは憎悪だ..しかし、それは働く唯一のものだと私は締め切り2日を持っている.. humm – Alex

2

ビューが再レンダリングされているときに、同じビューを再利用して、もう一度render()を呼び出すか、ビューを削除しますか?全く新しい視点を作り出していますか?

どちらの方法でも、ビューが再レンダリングされる前にビューイベントがアンバインドされていないように見えます。 Derick Baileyはこれについて素晴らしいpostを持っています。

あなたは再レンダリングすると、1)あなたは古いビュー内のすべてのイベントのバインドを解除していることを確認し、2)新しいビューを作成し、それ

+0

しかし、私は新しい親ビューを作ることができませんすべての子ビューが更新されるとき(親ビューは子ビューに応答しなければならない)。奇妙なことに、奇妙なことに私はこの記事の方法を試してみましたが、奇妙なことに、3回に1回、ページをリロードしました...何もありません... – Alex

1

それは選択された要素内のすべての子要素を削除して、選択した要素(el)の内部に任意の(子)要素にバインドあるALLイベント(およびデータ)を削除します。

子要素にバインドされたイベントを保つが、それでも子要素を削除し、使用:これはあなたのビューは、イベントで正常に再描画することを可能にする代わりに$(.el).empty();

$(el).children().detach();まだ縛られて働いている。

+1

@Alexあなたのコードで試してみてください: ''これ$ el.children()。detach()。append(nav).append(tabcontent); '' **完全に**動作するはずです。ビューのインスタンスを再作成する必要はありません。 – AmpT

+0

これらの回答を参考にしてください: http://stackoverflow.com/a/12029250/2728686および http://stackoverflow.com/a/7417078/2728686 – AmpT

関連する問題