当前位置: 代码迷 >> Web前端 >> renderTo跟applyTo的区别
  详细解决方案

renderTo跟applyTo的区别

热度:161   发布时间:2012-11-04 10:42:41.0
renderTo和applyTo的区别

Extjs的组件有两个看起来类似的配置项,applyTo和renderTo,这两个配置项都是用来指定将该extjs组件加载到什么位置。那他们到底有什么区别呢?

个人认为这两篇文章写的不够通俗。

写一个简单的例子来看看最终生成了什么代码。

<head> 
<title>RenderTo and ApplyTo</title> 
<link rel="Stylesheet" type="text/css" href="ext-3.1.0/resources/css/ext-all.css" /> 
<script type="text/javascript" src="ext-3.1.0/adapter/ext/ext-base-debug.js"></script> 
<script type="text/javascript" src="ext-3.1.0/ext-all-debug.js"></script> 
<script type="text/javascript" src="ext-3.1.0/src/locale/ext-lang-zh_CN.js"></script> 
<script type="text/javascript"> 
Ext.onReady(function() { 
var button = new Ext.Button({ 
renderTo: 'button', 
text:'OK' 
}); 

}); 
</script> 
</head> 
<body> 
<div id="button">sadfa</div> 
</body> 
</html> 

?此代码生成的html如下:

?

?

?如果是applyTo:button,则生成的代码为:


?很明显,简单的说,applyTo是将组件加在了指定元素之后,而renderTo则是加在指定元素之内。

?

接下来,我们再稍稍探寻下extjs源码的奥秘。看看extjs内部是如何使用这两个配置项的,利用firebug插件调试一下ext-all-debug.js这个文件。在Ext.Component的构造函数Ext.Component = function(config){…}中有这样一段代码(3.1.0版本是9270行):

if(this.applyTo){ 
this.applyToMarkup(this.applyTo); 
delete this.applyTo; 
}else if(this.renderTo){ 
this.render(this.renderTo); 
delete this.renderTo; 
} 

?可见applyTo属性使得Component调用applyToMarkup方法,而renderTo使得它调用render方法,并且如果两个都设置的话仅有applyTo有效,这点在extjs的文档中也有特别指出。
appylToMarkup方法如下(3.1.0版本是9560行)

applyToMarkup : function(el){ 
this.allowDomMove = false; 
this.el = Ext.get(el); 
this.render(this.el.dom.parentNode); 
} 

?

它最终调用的也是render,不过render的位置是parentNode,render方法如下(3.1.0版本是9370行)?

render : function(container, position){ 
if(!this.rendered && this.fireEvent('beforerender', this) !== false){ 
if(!container && this.el){ 
this.el = Ext.get(this.el); 
container = this.el.dom.parentNode; 
this.allowDomMove = false; 
} 
this.container = Ext.get(container); 
if(this.ctCls){ 
this.container.addClass(this.ctCls); 
} 
this.rendered = true; 
if(position !== undefined){ 
if(Ext.isNumber(position)){ 
position = this.container.dom.childNodes[position]; 
}else{ 
position = Ext.getDom(position); 
} 
} 
this.onRender(this.container, position || null); 
if(this.autoShow){ 
this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]); 
} 
if(this.cls){ 
this.el.addClass(this.cls); 
delete this.cls; 
} 
if(this.style){ 
this.el.applyStyles(this.style); 
delete this.style; 
} 
if(this.overCls){ 
this.el.addClassOnOver(this.overCls); 
} 
this.fireEvent('render', this); 

var contentTarget = this.getContentTarget(); 
if (this.html){ 
contentTarget.update(Ext.DomHelper.markup(this.html)); 
delete this.html; 
} 
if (this.contentEl){ 
var ce = Ext.getDom(this.contentEl); 
Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']); 
contentTarget.appendChild(ce); 
} 
if (this.tpl) { 
if (!this.tpl.compile) { 
this.tpl = new Ext.XTemplate(this.tpl); 
} 
if (this.data) { 
this.tpl[this.tplWriteMode](contentTarget, this.data); 
delete this.data; 
} 
} 
this.afterRender(this.container); 
if(this.hidden){ 
this.doHide(); 
} 
if(this.disabled){ 
this.disable(true); 
} 
if(this.stateful !== false){ 
this.initStateEvents(); 
} 
this.fireEvent('afterrender', this); 
} 
return this; 
} 

?

render的方法看起来相当的复杂,仔细阅读也能理解个大概,主要是为一个DOM节点设置class,可见性,在onRender方法中生成相应的HTML代码。

?

个人认为:el是紧紧包裹EXT组件的一个DOM节点,一般是由EXT自己生成,好像细胞膜一样,如果拨开了它,那么整个组件就显示的不完整,很可能显示的不正常。而render中的container(也就是applyTo的父原始,renderTo中的指定元素),是该组件的父元素,这个container可以是HTML代码,亦或是EXT组件。

综上所述:applyTo和renderTo没有本质上的区别,只是renderer的位置不同。


?

?

?

1 楼 xiaohui886688 2011-01-23  
不错,分析得挺不错。  
  相关解决方案