创建自定义的事件,然后透过RelayEvents与其他组件发生联系
程序员文章站
2024-02-03 13:05:22
...
我曾看到过一种现象,就是时下讨论着组件间如何交流通迅的人并不在少数,还有怎么使用这个relayEvents()函数。
没错,我也存在过相类似的问题。我现在终于明白,relayEvents()函数用在什么地方了,这是我写好一个程序后的收获。
现在不算太难搞了,可以说迎刃而解,也知道怎么把它运用起来。
代码解析
网页
网页文件本身是比较清晰直观的,如果你试过例子中的文件那么便能迅速了解这份JavaScript文件。接着以下三份文件将会作简单地说明:
* wcc.tree.js
* wcc.app.js
* relayEvents.js
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Relay Events</title>
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
<!-- GC -->
<!-- LIBS -->
<script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
<!-- ENDLIBS -->
<script type="text/javascript" src="../../ext-all.js"></script>
<script type="text/javascript" src="wcc.tree.js"></script>
<script type="text/javascript" src="wcc.app.js"></script>
<script type="text/javascript" src="relayEvents.js"></script>
<!-- Common Styles for the examples -->
<link rel="stylesheet" type="text/css" href="../shared/examples.css" />
</head>
<body>
<script type="text/javascript" src="../shared/examples.js">
</script><!-- EXAMPLES -->
<h1>Ext.relayEvents</h1>
<button id="theBtn">Run</button>
<p>这是没有经过混淆的文件便于阅读:
<ul style="margin-left:100px;">
<li><a href="wcc.tree.js">wcc.tree.js</a></li>
<li><a href="wcc.app.js">wcc.app.js</a></li>
<li><a href="relayEvents.js">relayEvents.js</a></li>
</ul>
</p>
</body>
</html>
自定义TreePanel
第一份文件(wcc.tree.js),是我自定义标准树TreePanel的扩展。另一种方式,将配置项作为参数传入的方式TreePanel,但是我没有使用这种方式,而是在我的程序中扩展后,周而复始地不断使用,简单地创建一个新扩展,不断实现化它就可以反复地使用。
我新建了一个treeLoader对象,使得采用“GET”的http请求进行通信,然后将onclick处理函数分配在每一个新建的节点上。
每个不同的节点或分支点击后都会触发自定义的事件“clickLeaf”或“clickBranch”,执行onclick处理函数。
/**
* 自定义的Tree,进行一些典型的设置,还有把TreeSorter对象新添加的事件加入到该组件中。
*/
Ext.ns("wcc"); // 建立属于自己部分的命名空间
wcc.tree = Ext.extend(Ext.tree.TreePanel, {
initComponent: function() {
// 开始配置组件!
this.rootID = this.rootID ? this.rootID : Ext.id();
Ext.apply(this, {
// 默认的配置项
animate:true,
autoScroll:true,
enableDD:true,
containerScroll: true,
// 定义tree loader
loader: new Ext.tree.TreeLoader( {
url : this.url,
requestMethod : "GET",
createNode : function( attr ) {
// 哪一种要触发的事件类型?
var NodeEvent = attr.leaf ? "clickLeaf" : "clickBranch";
attr.listeners = {
click : function( obj, evt, scope) {
// 触发自定义的事件
this.ownerTree.fireEvent(NodeEvent, this, attr, attr.text);
}
};
// 执行原来的方法
return Ext.tree.TreeLoader.prototype.createNode.call(this, attr);
}
}),
root : new Ext.tree.AsyncTreeNode({
text: this.rootID,
id : this.rootID,
expanded : true,
draggable : false
})
});
wcc.tree.superclass.initComponent.apply(this, arguments);
new Ext.tree.TreeSorter(this, {folderSort:true});
// 单击树节点时就会触发这两个新事件
this.addEvents( 'clickLeaf', 'clickBranch');
}
});
Ext.reg('wccTree', wcc.tree);
以下代码才是真正的自定义过程:
this.ownerTree.fireEvent(NodeEvent, this, attr, attr.text);
this.ownerTree代表wcc.tree的实例,触发刚才设置的事件,看看是“clickLeaf”还是“clickBranch”。
刚才这一行:
this.addEvents( 'clickLeaf', 'clickBranch' );
就是执行这里定义好的扩展事件。
Application Class
ok现在我们已经弄好一个TreePanel,并为将来的事件预留了相应的位置,接下来我们干什么好呢?
嗯我们看看qcc.app.js文件内的application class(我把涉及的类都封装在这个application中)。
强调一次这里没啥特别的地方,我尝试在“wcc”的命名空间中创建新类,里面的私有变量和方法可为不同的面板和窗体所服务。
wcc.app = function() {
// 私有的变量……
var win;
var button;
// 私有的方法……
var buildApp = function( cfg ) {
// 这是公有的配置
var dfltCfgParams = {
split : true,
collapsible : true,
margins : "3 0 3 3",
cmargins : "3 3 3 3"
};
// 设置导航树的配置项参数
var treeParams = Ext.apply( {
region : "west",
width : 200,
frame : true,
title : "Navigation"
}, cfg );
// 创建树面板
var tree = new wcc.tree(
Ext.apply( treeParams, dfltCfgParams )
);
// 创建content面板
var content = new Ext.Panel(Ext.apply({
title : "Content",
region : "center",
frame : true
}, dfltCfgParams ));
// 创建一个border layout风格的窗体,有tree和content面板
win = new Ext.Window({
title : 'Layout Window',
closable : true,
width : 600,
height : 350,
plain : true,
layout : 'border',
items : [ tree, content ]
});
// 关联tree的自定义事件“clickLeaf”和“clickBranch”
win.relayEvents(tree, ['clickLeaf', 'clickBranch']);
// 提供TreePanel对象的自定义处理函数。
// 例子中没有特别出彩的地方不过你可以加入更多
win.on( {
'clickLeaf' : function (nodeObj, nodeAttr, nodeText) {
console.log("Window - NodeClick - " + nodeText);
content.body.update("Hello World... Loading Text from Leaf: " + nodeObj.id);
},
'clickBranch' : function(nodeObj, nodeAttr, nodeText) {
console.log("Window - BranchClick - " + nodeText);
content.body.update("Hello World... Loading Text from Branch: " + nodeObj.id);
},
scope : this
});
};
// Public部分
return {
myTree : {},
root : {},
// 实际上我想把写好的类规范好以便调试和归档,但现在不是“产品的代码”
name : "wcc:App",
desc : "Generic App Class in private Namespace",
init : function(cfg) {
this.curFunc = this.name + ".init()";
button = Ext.get("theBtn");
button.on("click" , function() {
buildApp( cfg );
win.show(button);
});
}
}; // 返回公有部分(Public)
}();
再说一下这里关键的一行:
win.relayEvents(tree, ['clickLeaf', 'clickBranch']);
告诉这里的窗体可以中断并接着处理由Tree组件传入的“clickLeaf”和“clickBranch”事件。
最终一步
最后,这些代码就大功告成啦……
Ext.onReady( function() {
console.log("App running...");
wcc.app.init({
url : "getNodes.php",
rootID : "examples" // 此处为要显示的目录名称
});
}, wcc.app, true);
console.log("程序可以跑起来了……");
注意我是从别的TreePanel例子弄来的"getNodes.php"。
这样透过relayEvents()方法就可以简单而且灵活地事件编程,各组件之间的消息事件通信,和整个程序的层次结构、复杂的对象关系带来莫大的好处。
转http://www.extjs.com/learn/Tutorial:RelayEvents_%28Chinese%29
没错,我也存在过相类似的问题。我现在终于明白,relayEvents()函数用在什么地方了,这是我写好一个程序后的收获。
现在不算太难搞了,可以说迎刃而解,也知道怎么把它运用起来。
代码解析
网页
网页文件本身是比较清晰直观的,如果你试过例子中的文件那么便能迅速了解这份JavaScript文件。接着以下三份文件将会作简单地说明:
* wcc.tree.js
* wcc.app.js
* relayEvents.js
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Relay Events</title>
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
<!-- GC -->
<!-- LIBS -->
<script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
<!-- ENDLIBS -->
<script type="text/javascript" src="../../ext-all.js"></script>
<script type="text/javascript" src="wcc.tree.js"></script>
<script type="text/javascript" src="wcc.app.js"></script>
<script type="text/javascript" src="relayEvents.js"></script>
<!-- Common Styles for the examples -->
<link rel="stylesheet" type="text/css" href="../shared/examples.css" />
</head>
<body>
<script type="text/javascript" src="../shared/examples.js">
</script><!-- EXAMPLES -->
<h1>Ext.relayEvents</h1>
<button id="theBtn">Run</button>
<p>这是没有经过混淆的文件便于阅读:
<ul style="margin-left:100px;">
<li><a href="wcc.tree.js">wcc.tree.js</a></li>
<li><a href="wcc.app.js">wcc.app.js</a></li>
<li><a href="relayEvents.js">relayEvents.js</a></li>
</ul>
</p>
</body>
</html>
自定义TreePanel
第一份文件(wcc.tree.js),是我自定义标准树TreePanel的扩展。另一种方式,将配置项作为参数传入的方式TreePanel,但是我没有使用这种方式,而是在我的程序中扩展后,周而复始地不断使用,简单地创建一个新扩展,不断实现化它就可以反复地使用。
我新建了一个treeLoader对象,使得采用“GET”的http请求进行通信,然后将onclick处理函数分配在每一个新建的节点上。
每个不同的节点或分支点击后都会触发自定义的事件“clickLeaf”或“clickBranch”,执行onclick处理函数。
/**
* 自定义的Tree,进行一些典型的设置,还有把TreeSorter对象新添加的事件加入到该组件中。
*/
Ext.ns("wcc"); // 建立属于自己部分的命名空间
wcc.tree = Ext.extend(Ext.tree.TreePanel, {
initComponent: function() {
// 开始配置组件!
this.rootID = this.rootID ? this.rootID : Ext.id();
Ext.apply(this, {
// 默认的配置项
animate:true,
autoScroll:true,
enableDD:true,
containerScroll: true,
// 定义tree loader
loader: new Ext.tree.TreeLoader( {
url : this.url,
requestMethod : "GET",
createNode : function( attr ) {
// 哪一种要触发的事件类型?
var NodeEvent = attr.leaf ? "clickLeaf" : "clickBranch";
attr.listeners = {
click : function( obj, evt, scope) {
// 触发自定义的事件
this.ownerTree.fireEvent(NodeEvent, this, attr, attr.text);
}
};
// 执行原来的方法
return Ext.tree.TreeLoader.prototype.createNode.call(this, attr);
}
}),
root : new Ext.tree.AsyncTreeNode({
text: this.rootID,
id : this.rootID,
expanded : true,
draggable : false
})
});
wcc.tree.superclass.initComponent.apply(this, arguments);
new Ext.tree.TreeSorter(this, {folderSort:true});
// 单击树节点时就会触发这两个新事件
this.addEvents( 'clickLeaf', 'clickBranch');
}
});
Ext.reg('wccTree', wcc.tree);
以下代码才是真正的自定义过程:
this.ownerTree.fireEvent(NodeEvent, this, attr, attr.text);
this.ownerTree代表wcc.tree的实例,触发刚才设置的事件,看看是“clickLeaf”还是“clickBranch”。
刚才这一行:
this.addEvents( 'clickLeaf', 'clickBranch' );
就是执行这里定义好的扩展事件。
Application Class
ok现在我们已经弄好一个TreePanel,并为将来的事件预留了相应的位置,接下来我们干什么好呢?
嗯我们看看qcc.app.js文件内的application class(我把涉及的类都封装在这个application中)。
强调一次这里没啥特别的地方,我尝试在“wcc”的命名空间中创建新类,里面的私有变量和方法可为不同的面板和窗体所服务。
wcc.app = function() {
// 私有的变量……
var win;
var button;
// 私有的方法……
var buildApp = function( cfg ) {
// 这是公有的配置
var dfltCfgParams = {
split : true,
collapsible : true,
margins : "3 0 3 3",
cmargins : "3 3 3 3"
};
// 设置导航树的配置项参数
var treeParams = Ext.apply( {
region : "west",
width : 200,
frame : true,
title : "Navigation"
}, cfg );
// 创建树面板
var tree = new wcc.tree(
Ext.apply( treeParams, dfltCfgParams )
);
// 创建content面板
var content = new Ext.Panel(Ext.apply({
title : "Content",
region : "center",
frame : true
}, dfltCfgParams ));
// 创建一个border layout风格的窗体,有tree和content面板
win = new Ext.Window({
title : 'Layout Window',
closable : true,
width : 600,
height : 350,
plain : true,
layout : 'border',
items : [ tree, content ]
});
// 关联tree的自定义事件“clickLeaf”和“clickBranch”
win.relayEvents(tree, ['clickLeaf', 'clickBranch']);
// 提供TreePanel对象的自定义处理函数。
// 例子中没有特别出彩的地方不过你可以加入更多
win.on( {
'clickLeaf' : function (nodeObj, nodeAttr, nodeText) {
console.log("Window - NodeClick - " + nodeText);
content.body.update("Hello World... Loading Text from Leaf: " + nodeObj.id);
},
'clickBranch' : function(nodeObj, nodeAttr, nodeText) {
console.log("Window - BranchClick - " + nodeText);
content.body.update("Hello World... Loading Text from Branch: " + nodeObj.id);
},
scope : this
});
};
// Public部分
return {
myTree : {},
root : {},
// 实际上我想把写好的类规范好以便调试和归档,但现在不是“产品的代码”
name : "wcc:App",
desc : "Generic App Class in private Namespace",
init : function(cfg) {
this.curFunc = this.name + ".init()";
button = Ext.get("theBtn");
button.on("click" , function() {
buildApp( cfg );
win.show(button);
});
}
}; // 返回公有部分(Public)
}();
再说一下这里关键的一行:
win.relayEvents(tree, ['clickLeaf', 'clickBranch']);
告诉这里的窗体可以中断并接着处理由Tree组件传入的“clickLeaf”和“clickBranch”事件。
最终一步
最后,这些代码就大功告成啦……
Ext.onReady( function() {
console.log("App running...");
wcc.app.init({
url : "getNodes.php",
rootID : "examples" // 此处为要显示的目录名称
});
}, wcc.app, true);
console.log("程序可以跑起来了……");
注意我是从别的TreePanel例子弄来的"getNodes.php"。
这样透过relayEvents()方法就可以简单而且灵活地事件编程,各组件之间的消息事件通信,和整个程序的层次结构、复杂的对象关系带来莫大的好处。
转http://www.extjs.com/learn/Tutorial:RelayEvents_%28Chinese%29