extjs - 将 ExtJS MVC Controller 附加到 DOM 元素,而不是组件

标签 extjs extjs4 extjs-mvc

有没有办法使用 Ext.app.Controller control() 方法,但传入一个 DOM 查询?我有一个包含标准链接的页面,并且希望向它们添加点击处理程序,即使它们不是作为 Ext 按钮创建的。

我试过了

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

    init: function() {
        console.log("init");
        this.control({
            'a': {
                click: this.changeTab
            }   
        });
    },

    changeTab: function() {
        alert("new tab!");
    }   
});

但是单击链接不会触发警报。

有没有办法用 this.control 指定 CSS 选择器?或者它只适用于组件?

最佳答案

我在今年的 SenchaCon 上问了这个问题,Sencha 开发人员表示他们的意图是 DOM 监听器应该附加到您的 View 中,并且 View 应该将它们抽象为更有意义的组件事件并重新触发它们。

例如,假设您正在创建一个名为 UserGallery 的 View ,该 View 显示了一个人脸网格。在您的 UserGallery View 类中,您将监听 <img> 上的 DOM 点击事件。标记来接收事件和目标,然后 View 可能会触发一个名为“userselected”的组件事件,并为单击的用户传递模型实例而不是 DOM 目标。

最终目标是只有您的 View 应该关注界面事件和 DOM 元素等事情,而应用程序级 Controller 只处理有意义的用户意图。您的应用程序和 Controller 代码根本不应该与您的标记结构或接口(interface)实现耦合。

示例 View

Ext.define('MyApp.view.UserGallery', {
    extend: 'Ext.Component'
    ,xtype: 'usergallery'

    ,tpl: '<tpl for="users"><img src="{avatar_src}" data-ID="{id}"></tpl>'

    ,initComponent: function() {
        this.addEvents('userselected');

        this.callParent(arguments);
    }

    ,afterRender: function() {
        this.mon(this.el, 'click', this.onUserClick, this, {delegate: 'img'});

        this.callParent(arguments);
    }

    ,onUserClick: function(ev, t) {
        ev.stopEvent();

        var userId = Ext.fly(t).getAttribute('data-ID');

        this.fireEvent('userselected', this, userId, ev);
    }
});

View 注释
  • 扩展“Ext.Component”当你想要的只是一个托管的<div> , Ext.Panel 在支持标题栏、工具栏、折叠等方面要重得多。
  • 在将监听器附加到组件中的 DOM 元素时使用“托管”侦​​听器(请参阅 Component.mon)。当组件被销毁时,由组件管理的监听器将自动释放
  • 当从多个 DOM 元素监听相同事件时,使用“委托(delegate)”事件选项并将监听器附加到它们的公共(public)父级而不是单个元素。这表现得更好,让您可以任意创建/销毁子元素,而不必担心不断地将事件监听器附加/删除到每个子元素。避免使用 .select('img').on('click', handler) 之类的东西
  • 从 View 触发事件时,Sencha 的约定是事件的第一个参数是 scope -- 对触发事件的 View 的引用。当从 Controller 处理事件时,这很方便,您需要将事件处理程序的实际范围作为 Controller 。

  • sample Controller
    Ext.define('app.controller.myController', {
        extend: 'Ext.app.Controller'
    
        ,init: function() {
            this.control({
                'usergallery': {
                    userselected: function(galleryView, userId, ev) {
                        this.openUserProfile(userID);
                    }
                }   
            });
        }
    
        ,openUserProfile: function(userId) {
            alert('load another view here');
        }
    });
    

    关于extjs - 将 ExtJS MVC Controller 附加到 DOM 元素,而不是组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6047862/

    相关文章:

    extjs - 如何解决 ExtJS "Synchronously loading"警告

    extjs - 覆盖 Ext.util.Format.thousandSeparator 除非格式化货币

    javascript - 如何设置 Ext.button.Split 在菜单为空时不显示箭头?

    javascript - 网格显示没有数据,但有请求直接为什么

    Extjs: (TimeField) 重置 minValue 和 maxValue

    extjs - EXT JS 5.1 Minified Core Frame work 开发时

    javascript - Ext.ComponentLoader 在组件内延迟加载 html+js

    javascript - 什么时候不遵守 z-index?

    javascript - 在 ExtJS4 中悬停时获取网格单元格值

    javascript - 如何在点击时运行事件加载?