2013-11-29 25 views
1

希望有人可以遮蔽一些洞察這個問題......一直在我的頭撞牆。自定義事件監聽器沒有添加到控制器後容器被破壞一次

問題: 我有一個名爲「showCommentPanel」的自定義事件附加到名爲「StoryDe​​tailPanel」的視圖。 「StoryDe​​tailPanel」上的代理監聽器監聽輕敲,然後在該函數內部觸發「showCommentPanel」。該事件被控制器捕獲並執行某些操作。 「StoryDe​​tailPanel」是一個動態創建的視圖,它被推送並從導航視圖中移除。 我的問題是,當第一次顯示StoryDe​​tailPanel時,整個設置工作。點擊DOM元素被捕獲,事件被解僱,控制器得到事件。但是,按下「後退」按鈕並創建了一個新的StoryDe​​tailPanel後,Tap on DOM元素被捕獲,但「showCommentPanel」沒有被控制器捕獲。

代碼:

StoryDe​​tailPanel查看

Ext.define('Test.view.StoryDetailPanel', { 
    extend: 'Ext.Container', 
    alias: 'widget.storydetailpanel', 

    config: { 
     cls: 'storydetailpanel', 
     id: 'storydetailpanel', 
     layout: { 
      type: 'fit' 
     }, 
     scrollable: 'vertical', 
     items: [ 
      { 
       xtype: 'container', 
       id: 'infodetailcontainer', 
       itemId: 'mycontainer3', 
       margin: '2% 5% 0px 5%', 
       tpl: [ 
        '<div class=\'detailinfo\'>', 
        ' <div class=\'container\'>', 
        '  <div class=\'actions\'>', 
        '   <div class=\'comments\'>', 
        '    <div class=\'text\'>COMMENT</div>', 
        '   </div>', 
        '  </div>', 
        ' </div>', 
        '</div>', 
        '', 
        '' 
       ], 
       layout: { 
        type: 'fit' 
       } 
      } 
     ], 
     listeners: [ 
      { 
       fn: 'onCommentTap', 
       element: 'element', 
       event: 'tap', 
       delegate: 'div.actions .comments' 
      }, 
      { 
       fn: 'onStorydetailpanelShowCommentPanel', 
       event: 'showCommentPanel' 
      } 
     ] 
    }, 

    onCommentTap: function(target) { 
     alert('comment tapped: '+this.id); 
     //TODO: remove hard coding later 
     var postId = 7; 
     this.fireEvent("showCommentPanel", postId); 
    }, 

    onStorydetailpanelShowCommentPanel: function(postId, eventOptions) { 
     alert("show comment panel caught in story detail"); 
    } 

}); 

控制器

Ext.define('Test.controller.Post', { 
    extend: 'Ext.app.Controller', 

    config: { 
     refs: { 
      storydetailpanel: 'storydetailpanel', 
     }, 

     control: { 
      "#storydetailpanel": { 
       showCommentPanel: 'onStorydetailpanelShowCommentPanel', 
      } 
     } 
    }, 

    onStorydetailpanelShowCommentPanel: function(postId, eventOptions) { 
     alert('show event caught in controller'); 
    }, 

}); 

與 「StoryDe​​tailPanel」 被添加到導航視圖這樣

var details = Ext.create('Test.view.StoryDetailPanel', { 
    title: 'Details' 
}); 

this.getMainNav().push(details); 

所以這裏的情景:

  1. 「螺紋評論」始終是驚動當評論DIV是 抽頭「夾縫中的故事細節顯示評論面板」
  2. 後總是提醒所有的時間「評論點擊」
  3. 「show event caught in controller」僅顯示第一次即顯示storydetailpanel。點擊「返回」後,做任何觸發一個新的storydetail面板被推入。點擊註釋div只會觸發#1和#2。

EDITED 多一點信息, 只要我沒有按後退按鈕(即保持停留在同一StoryDe​​tailPanel查看它裝在第一時間),一切工作和活動將被控制器捕獲。所以我懷疑破壞StoryDe​​tailPanel的第一個實例與殺死監聽器有關?

我在google和stackoverflow上搜了很多,找不到解決方案...任何幫助將不勝感激!

回答

1

所以,我沒有把頭撞在牆上,而是嘗試着去嘗試和錯誤,我決定深入到sencha觸摸代碼中,我想我現在大部分都知道發生了什麼..... 無論如何,理解監聽器被保存在一個叫做Dispatcher的單例中是很有用的。而聽衆與呼叫者對象一起生活和死亡。所以一旦對象被銷燬,監聽器實例就會從Dispatcher中移除。當一個對象被實例化時,那個容器的事件監聽器會被重新加入。發生了什麼事情是「destroy()」調用顯然破壞了任何機制來控制在創建容器的新實例時添加什麼事件監聽器(可能一些殘留的跟蹤器沒有清除,並且跳過了添加偵聽器而沒有意識到它已被刪除)。

這種行爲已通過destroy()調用之前和之後通過調度程序中的偵聽器堆棧驗證,以及容器實例化之後。

無論如何,知道這一點,解決方法變得非常明顯,我認爲它是乾淨的,非侵入性的,我願意與它一起生活......現在。

基本上,當您創建和動態刪除容器時,只要確保在創建創建容器後添加偵聽器的額外步驟即可。所以在我的例子

functionThatCreatesDetailPanelInController: function() { 
var detailpanel = <Code that creats my detailpanel> 
//add listener for custom event 
detailpanel.on('showCommentPanel', this.onDetailpanelShowCommentPanel, this); 

< add detailpanel into view ... > 

} 

希望這有助於。

+0

這就是我一直在做的事情:在視圖初始化上綁定事件 –

0

+1。從很早的時候開始與Sencha Touch合作時,我遇到過這個問題。

有可能是解決在這個崗位你的問題的機會:button tap not reacting when view gets added a 2nd time

但對我來說,它沒有。這就是爲什麼我從使用控制器很長一段時間以來的原因,因爲我不認爲在大型應用程序中使用它是一種很好的做法,我們必須非常頻繁地添加和刪除視圖。

我相信這是一個錯誤。

+0

我剛剛對您鏈接的帖子做了快速掃描。感謝您回覆Thiem。我還編輯了我原來的問題,說只要視圖沒有被破壞,一切都會按預期工作。巧合的是,你鏈接的線程提到關於將autodestroy設置爲false ....以至於說有一些東西確實與對象的銷燬有關。我只想知道我是否應該放棄這個[View - > fireevent-> Controller忙碌工作]範式,我正在追求。 – JChow