容器被销毁一次后,自定义事件监听器未添加到Controller

时间:2013-11-29 06:23:45

标签: sencha-touch sencha-touch-2

希望有人可以对这个问题有所了解......一直把我的头撞在墙上一段时间。

问题: 我有一个名为“showCommentPanel”的自定义事件附加到名为“StoryDe​​tailPanel”的视图。 “StoryDe​​tailPanel”上的委托侦听器侦听一个tap,然后在该函数内触发“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. 后收到提醒
  4. “在控制器中捕获的节目事件”仅显示了故事板尾部显示的首次。点击“返回”并执行任何触发新故事引导的内容。点击注释div只会触发#1和#2。
  5. 已编辑 更多信息, 只要我 DID NOT 按下后退按钮(即第一次加载时保持在相同的StoryDe​​tailPanel视图中),一切正常,事件将被捕获到控制器中。所以我怀疑破坏StoryDe​​tailPanel的第一个实例与杀死听众有什么关系?

    我在谷歌和stackoverflow上搜索了很多,但找不到解决方案......任何帮助都将不胜感激!

2 个答案:

答案 0 :(得分: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 ... >

}

希望这有帮助。

答案 1 :(得分:0)

+1的问题。从很早的时候开始与Sencha Touch合作,我经常遇到过这个问题。

在这篇文章中可能有机会解决您的问题:button tap not reacting when view gets added a 2nd time

但对我来说,事实并非如此。这就是我在很长一段时间内使用控制器的原因,因为我不相信在大型应用程序中使用它是一种很好的做法,我们必须经常添加和删除视图。

我相信这是一个错误。