`
yiminghe
  • 浏览: 1437822 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Ext Composite 应用注意

阅读更多

首先看一段代码 :

 

<!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

Creates a Ext.CompositeElement for child nodes based on the passed CSS selector (the selector should not contain an id).
Creates a Ext.CompositeElement for child nodes based on the passed CSS selector (the selector should not contain an id).
Parameters:
  • selector : String
    The 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)
Returns:
  • CompositeElement/CompositeElementLite
    The composite element
上述代码 使用的不是 unique ,所以 子节点共用了一个 Ext.Element.Flyweight ,若要为每个子元素都给一个 Ext.Element,则要调用

Ext.select('selector',true);


select("")与select("",true)不同点在于 不带true时返回CompositeElementLite,内部所有元素共享一个Ext.Element.Flyweight,而带true时返回CompositeElement,内部所有元素都是单独的Ext.Element


addListener 与 CompositeElementLite 注意:

由于CompositeElementLite与CompositeElement会自动把Element.prototype自动附加到自己的prototype身的,并且加入循环控制。
但是有一点注意:
Element 的 addListene中的 scope 默认为 this :

addListener : function(eventName, fn, scope, options){
        Ext.EventManager.on(this.dom,  eventName, fn, scope || this, options);
        return this;
    },
 
则由前可知CompositeElementLite共享一个Element则如果添加循环后,this则会一直指向CompositeElementLite最后的那个element,不过CompositeElementLite已经考虑到了这个问题,单独处理了这个问题:
// 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);});
 this在CompositeElementLite中为当前的HTML DOM类型
而this在CompositeElement中则为Ext.Element

大家注意一下吧 ,建议:

Ext.select("a").on("click",function(){var el=Ext.fly(this);console.log(el);});

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics