将ExtJS MVC控制器附加到DOM元素,而不是组件 [英] Attach ExtJS MVC controllers to DOM elements, not components

查看:103
本文介绍了将ExtJS MVC控制器附加到DOM元素,而不是组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我尝试过

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

init:function(){
console.log(init);
this.control({
'a':{
click:this 。$。


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

但点击链接不会触发警报。



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

解决方案

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



例如,假设您正在创建一个视图称为UserGallery,显示人脸的网格。在您的UserGallery视图类中,您将收听< img> 标签上的DOM点击事件以接收事件和目标,然后视图可能会触发称为userselected并传递所点击的用户的模型实例,而不是DOM目标。



最终目标是只有您的观点应该关注接口事件和DOM元素,而应用程序级控制器只处理有意义的用户意图。您的应用程序和控制器代码不应该与您的标记结构或接口实现相结合。



样本视图



  Ext.define('MyApp.view.UserGallery',{
extends:'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参数);
}

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

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

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



意见说明




  • 扩展Ext.Component,当您想要的是一个受管理的< div> 时,Ext.Panel要支持诸如标题栏,工具栏,折叠等。

  • 在组件的DOM元素中添加侦听器时使用受管理侦听器(请参阅Component.mon)。当组件被销毁时,组件管理的侦听器将被自动释放。

  • 当从多个DOM元素中侦听相同的事件时,使用delegate事件选项,并将侦听器附加到其常见的父母而不是个人元素。这样做更好,让您可以任意地创建/销毁子元素,而不必担心会不断地为每个孩子附加/删除事件监听器。避免使用类似 .select('img')。on('click',handler)

  • 从视图中,Sencha的约定是事件的第一个参数是 scope - 引用事件的视图。当控制器处理事件时,这是方便的,您需要事件处理程序的实际范围作为控制器。



< h2>样本控制器

  Ext.define('app.controller.myController',{
extends:'Ext。 app.Controller'

,init:function(){
this.control({
'usergallery':{
userselected:function(galleryView,userId,ev ){
this.openUserProfile(userID);
}
}
});
}

,openUserProfile:function(userId) {
alert('load other view here');
}
});


Is there a way to use the Ext.app.Controller control() method, but pass in a DOM query? I have a page that contains standard links and would like to add a click handler to them even though they were not created as Ext Buttons.

I've tried

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!");
    }   
});

But clicking on links does not fire the alert.

Is there a way to specify a CSS selector with this.control? Or does it only work with components?

解决方案

I asked this question at SenchaCon this year, the Sencha developers stated that their intent is that DOM listeners should be attached within your view, and the view should abstract them into more meaningful component events and refire them.

For example, suppose you're creating a view called UserGallery that shows a grid of people's faces. Within your UserGallery view class, you would listen for the DOM click event on the <img> tag to receive event and target, and then the view might fire a component event called "userselected" and pass the model instance for the clicked user instead of the DOM target.

The end goal is that only your views should be concerned with things like interface events and DOM elements while the application-level controller only deals with meaningful user intents. Your application and controller code shouldn't be coupled to your markup structure or interface implementation at all.

Sample 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);
    }
});

Notes on views

  • Extend "Ext.Component" when all you want is a managed <div>, Ext.Panel is a lot heavier to support things like titlebars, toolbars, collapsing, etc.
  • Use "managed" listeners when attaching listeners to DOM elements from a component (see Component.mon). Listeners managed by a components will be automatically released when that component gets destroyed
  • When listening for the same event from multiple DOM elements, use the "delegate" event option and attach the listener to their common parent rather than to individual elements. This performs better and lets you create / destroy child elements arbitrarily without worrying about continuously attaching/removing event listeners to each child. Avoid using something like .select('img').on('click', handler)
  • When firing an event from a view, Sencha's convention is that the first parameter to the event be scope -- a reference to the view that fired the event. This is convenient when the event is being handled from a controller where you'll need the actual scope of the event handler to be the 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 MVC控制器附加到DOM元素,而不是组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆