首先看一段代码 :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>composite 测试</title>
<script type='text/javascript' src='ext-base.js'></script>
<script type='text/javascript' src='ext-core.js'></script>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script type='text/javascript'>
Ext.onReady(function(){
var tests=[];
Ext.select('ul li').each(function(el,this_,index_i) {
var ob=el;
//或者
//ob=this_.item(index_i);
tests.push(ob);
});
for(var i=0;i<tests.length;i++) {
alert(tests[i].dom.innerHTML);
}
}) ;
</script>
</body>
</html>
我们期望输出 1 2 3,可实际上输出 3 3 3,总可以看出得到的全部对象实际上是一个 Ext.Element 对象。
即Ext 默认在遍历 对象集合时用了 flyweight, 返回组合对象为Ext.CompositeElementLite
(select 参数第二个 ,默认为false,各个子节点共用一个 Ext.Element.Flyweight)
From Extjs:
Ext.Element.select = function(selector, unique, root){
var els;
if(typeof selector == "string"){
els = Ext.Element.selectorFunction(selector, root);
}else if(selector.length !== undefined){
els = selector;
}else{
throw "Invalid selector";
}
return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els);
};
若要强制不要进行共享ext对象,则要构造一个全新的 Ext对象,即可得的解决方法
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>composite 测试</title>
<script type='text/javascript' src='ext-base.js'></script>
<script type='text/javascript' src='ext-core.js'></script>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script type='text/javascript'>
Ext.onReady(function(){
var tests=[];
Ext.select('ul li').each(function(el,this_,index_i) {
//强制不要共享了,构造一个自己的ext 对象
var ob=Ext.get(el.dom)
tests.push(ob);
});
for(var i=0;i<tests.length;i++) {
alert(tests[i].dom.innerHTML);
}
}) ;
</script>
</body>
</html>
由此可见,在应用 ext CompositeLite 时 ,要么 在 each 中一次性解决当前问题 ,要么 构造新的对象 后期处理,特别是在 each 中 要进行事件处理的 ,要特别小心,最好 构造新的对象 添加事件listener ,见如下 代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>composite 测试</title>
<script type='text/javascript' src='ext-base.js'></script>
<script type='text/javascript' src='ext-core.js'></script>
<style type='text/css'>
li {
border :2px solid green;
margin:30px;
cursor:pointer;
}
</style>
</head>
<body>
<ul>
<li>clicke me 1</li>
<li>clicke me 2</li>
<li>clicke me 3</li>
</ul>
<script type='text/javascript'>
Ext.onReady(function(){
var tests=[];
//强制不共享
Ext.select('ul li',true).each(function(el,this_,index_i) {
el.on('click' ,function() {
alert(el.dom.innerHTML);
});
});
//手动不共享
Ext.select('ul li').each(function(el,this_,index_i) {
//正确
var ob=Ext.get(el.dom);
//错误1
//var ob=el;
//或 错误2
//var ob=this_.item(index_i);
ob.on('click' ,function() {
alert(ob.dom.innerHTML);
});
});
}) ;
</script>
</body>
</html>
注:select ( String selector , [Boolean unique ] ) : CompositeElement/CompositeElementLite
-
selector: StringThe CSS selector -
unique: Boolean(optional) True to create a unique Ext.Element for each child (defaults to false, which creates a single shared flyweight object)
-
CompositeElement/CompositeElementLiteThe composite element
unique ,所以 子节点共用了一个 Ext.Element.Flyweight ,若要为每个子元素都给一个
Ext.Element,则要调用
addListener : function(eventName, fn, scope, options){
Ext.EventManager.on(this.dom, eventName, fn, scope || this, options);
return this;
},
// fixes scope with flyweight
addListener : function(eventName, handler, scope, opt){
var els = this.elements,
len = els.length,
i, e;
for(i = 0; i<len; i++) {
e = els[i];
if(e) {
Ext.EventManager.on(e, eventName, handler, scope || e, opt);
}
}
return this;
},
Ext.select("a").on("click",function(){console.log(this);});
Ext.select("a",true).on("click",function(){console.log(this);});
Ext.select("a").on("click",function(){var el=Ext.fly(this);console.log(el);});
本文详细解析了ExtJS中CompositeElement与CompositeElementLite的区别,特别是它们在事件监听处理上的不同行为。通过实例代码展示了如何避免使用共享对象,并提供了解决方案。
179

被折叠的 条评论
为什么被折叠?



