• Extjs学习笔记之五——一个小细节renderTo和applyTo的区别


    Extjs的组件有两个看起来类似的配置项,applyTo和renderTo,这两个配置项都是用来指定将该extjs组件加载到什么位置。那他们到底有什么区别呢,网上搜了下,有两篇博文也是关于这个的,

    ExtJS中的renderTo和applyTo的差别

    对applyTo和renderTo的理解和思考

    个人认为这两篇文章写的不够通俗。写一个简单的例子来看看最终生成了什么代码,

    <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如下:

    image

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

    image

    很明显,简单的说,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代码。在 对applyTo和renderTo的理解和思考 中提到的el配置属性,我查extjs的文档发现这是一个只读属性,虽然有方法覆盖它,不过一般不需要手动设置,下面是Panel的公共属性el的文档原文:

    el : Ext.Element

    The Ext.Element which encapsulates this Component. Read-only.

    This will usually be a <DIV> element created by the class's onRender method, but that may be overridden using the autoEl config.

    Note: this element will not be available until this Component has been rendered.

    所以我估计此文写的是以前版本的extjs。个人认为,el是紧包裹着extjs组件的一个DOM节点,一般是由extjs自己生成的,好像细胞膜一样,如果拨开了它,那么这个组件就不完整了,很可能会表现的不正常。而render方法中的container(也就是applyTo中指定元素的父元素,renderTo中指定的元素),是该组件的父元素,这个container中可以包括其他的html元素或者extjs组件。

    综上所述,其实applyTo和renderTo没有很本质区别,只是render的位置不同。

  • 相关阅读:
    MultipartFile(文件的上传)
    JSONObject.fromObject--JSON与对象的转换
    Map集合与转化
    java读取excel文件
    Java中的Arrays类使用详解
    Arrays 类的 binarySearch() 数组查询方法详解
    JDK8 特性详解
    关于Java堆、栈和常量池的详解
    深入java final关键字
    杯酒人生
  • 原文地址:https://www.cnblogs.com/yinzixin/p/1640233.html
Copyright © 2020-2023  润新知