有没有办法使用Ext.app.Controller control()方法,但传入DOM查询?我有一个包含标准链接的页面,并希望为它们添加一个单击处理程序,即使它们不是作为Ext Buttons创建的。
我试过
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选择器?或者它只适用于组件?
答案 0 :(得分:3)
我找到了解决这个问题的方法。它并不像人们希望的那样直接,但它会将所有“动作”代码留在控制器中。
要求:将网页的html部分包含在实际的Ext.Component
中。无论哪种方式都可能出现这种情况。例如,您可能有一个包含HTML的简单视图,如下所示:
Ext.define('app.view.myView', {
extend: 'Ext.panel.Panel',
alias: 'widget.myView',
title: 'My Cool Panel',
html: '<div><a href="#">This link will open a window</a></div><br /> <label for="myInput">Type here: </label><input name="myInput" type="text" value="" />',
initComponent: function(){
var me = this;
me.callParent(arguments);
}
});
然后在控制器中使用afterrender
事件将侦听器应用于DOM元素。在下面的示例中,我将说明链接(元素)和输入元素:
Ext.define('app.controller.myController', {
extend: 'Ext.app.Controller',
init: function() {
this.control({
'myView': {
afterrender: function(cmp){
var me = this; //the controller
var inputs = cmp.getEl().select('input'); // will grab all DOM inputs
inputs.on('keyup', function(evt, el, o){
me.testFunction(el); //you can call a function here
});
var links = cmp.getEl().select('a'); //will grab all DOM a elements (links)
links.on('click', function(evt, el, o){
//or you can write your code inline here
Ext.Msg.show({
title: 'OMG!',
msg: 'The controller handled the "a" element! OMG!'
});
});
}
}
});
},
testFunction: function(el) {
var str = 'You typed ' + el.value;
Ext.Msg.show({
title: 'WOW!',
msg: str
});
}
});
你有它,DOM元素在控制器内处理并坚持MVC架构!
答案 1 :(得分:1)
不,这似乎不可能。 Ext.EventBus侦听ExtJS组件触发的事件。您的标准DOM元素不会触发这些事件。另外,使用ExtJS组件检查查询(String selector)方法,这些方法不能被DOM元素调用。如果我错了,有人可能会纠正我,但不幸的是,我很确定这是不可能的。
答案 2 :(得分:0)
我也有一个可以解决这个问题的解决方案。我使用这种技术,不过因为它有其他好处:我创建了一个应用程序范围的消息传递总线。它是我的应用程序中的一个对象,它扩展了Observable,并定义了一些事件。然后,我可以在我的应用程序中触发任何事件,包括html链接。任何想要监听这些事件的组件都可以转发它们,并且它们会像从该组件触发一样触发。
Ext.define('Lib.MessageBus', {
extend: 'Ext.util.Observable',
constructor: function() {
this.addEvents(
"event1",
"event2"
);
this.callParent(arguments);
}
});
然后,每个其他组件可以在初始化后添加:
this.relayEvents('Lib.MessageBus', ['event1','event2']);
然后听那些事件。 您可以通过执行以下操作来触发事件:
Lib.MessageBus.fireEvent('event1', 'param a', 'param b')
你可以从包括html链接在内的任何事情中做到这一点。
将应用程序的某个部分的事件发送到另一部分非常方便。
答案 3 :(得分:0)
我最近遇到了同样的问题(将mvc与一些非组件混合)。 只是想我会把它作为一个答案,因为它似乎很简单,对我有用:)
Ext.define('app.controller.TabController', {
extend: 'Ext.app.Controller',
init: function() {
console.log("init");
this.control({
/* 'a': {
click: this.changeTab
} */
});
var link = Ext.dom.Query.selectNode('a');
Ext.get(link).on('click', this.changeTab);
},
changeTab: function() {
alert("new tab!");
}
});