HTML 和 ExtJS 组件(一)

你要创建一个网页时, 经常会发现,你知道怎样用原生的html来创建,却不知道如何使用浩如烟海的ext组件来实现。本文将介绍一些使用ext组件创建html的一些技巧。

简介

组件的渲染
首先让我们用一个简单的例子了解一下组件是如何渲染的:

/** The renderTo config option specifies a parent DOM element for
 *  rendering the component.
 *  For brevity it is not shown in the remaining examples.
 */  
new Ext.Component({renderTo: 'component-demo' });

这个例子太简单了,我们甚至在页面上无法看到它:

但是它的确生成了下面的dom元素:

<div id="component-1001" class="x-component x-component-default" role="presentation"></div>

我们先暂停一下

  1. 一个ext组件使用一个
    进行渲染,复杂的html元素也许会使用很多的html元素进行渲染,但有且只有一个外部元素作为组件的基本元素,组件渲染完成后你可以通过组件对象的el属性来访问这个元素。
  2. 基本元素的ID即是组件的id;
  3. 这里有两个css, 分别来自baseCls和ui两个配置项,这两个配置项提供有默认值,我们在创建ext组件时很少用到。稍后我们会看一个使用baseCls的例子。
  4. 基于你使用的ext版本,你会看到其他不同的配置属性,如ARIA。

现在让我们简化一下上面的html元素, 以方便描述:

<div id="component-1001" ...></div>

让我们给ext组件添加一些样式苏醒,以方便我们看到这个组件:

new Ext.Component({ cls: 'green-box',height: 60, width: 300 });
.green-box {     
            background-color: #fec;     
            border: 2px solid #5a7;     
            border-radius: 5px;     
            box-shadow: 2px 2px 2px #bbb;     
            padding: 5px; 
}

我们在ext组件中添加的这些属性会生成如下的html元素样式:

<div id="component-1001" class="green-box ..." style="height: 60px; width: 300px;" ...></div>

现在以这个组件为本例子的基础,让我们开始添加自己的html:

html属性配置

简单粗暴, 我们可以通过配置html字符串来将我们的html注入到ext组件:

new Ext.Component({html: 'Some <b>HTML</b> content',     ... });

生成的html如下:

<div id="..." class="green-box x-component x-component-default" ...>     
       Some <b>HTML</b> content 
</div>

现在静态注入的html已经很好的执行了,我们还可以通过组件的update方法来替换html的内容:

var summary = new Ext.Component({html: 'Some <b>content</b>',     ... });  
new Ext.button.Button({     
         ...      
        handler: function() {         
        summary.update('Some slightly different <b>content</b>');     
} });

点击按钮, summary中的html会改变:

<div id="..." class="green-box x-component x-component-default" ...>     
       Some slightly different <b>content</b>
</div>

可是,使用html配置项我们只能改变组件里面的内容,如果我们想要改变组件外部的el本身,就得通过别的途径来实现了。

autoEl属性

我们可以通过配置autoEl属性来改变组件外部的el元素:

new Ext.Component({     autoEl: 'form',     ... });

它看起来和刚才的例子很相像,但是生成的html却改变了(原来是个div,现在是个form):

<form id="..." class="green-box x-component x-component-default" ...></form>

通过给autoEl配置object对象,我们还可以改变组件el的其他结构。比如,我们可以添加一些简单属性给这个html:

new Ext.Component({     
           autoEl: {         
                       href: 'javascript:alert(%22Clicked!%22)',        
                       html: 'Click Me!',         
                       tag: 'a'     
            } 
});

这时,生成的html如下:

<a href="javascript:alert(%22Clicked!%22)" ...>Click Me!</a>

autoEl实质上是作为一个DomHelper来渲染的,因此它能接受所有DomHelper的配置项;比如通过cn来创建子元素:
new Ext.Component({
     ...
      autoEl: {
         cn: [
             'Some ',
             {tag: 'b', cn: 'HTML'},
             ' content'
         ]
     } 
});

Html代码

<div ...>  Some <b>HTML</b> content </div>

虽然autoEl很好很强大,但是它也有缺陷:它很难通过参数配置,并且代码可读性很差。如果你需要添加一个内容生动的ext组件,使用模板将是更好的选择。

tpl 和 data 属性
这两个属性需要同时使用。tpl提供一个html模板(XTemplate 语法),data为模板提供渲染数据。

通俗地讲, tpl就像声明了一个类,而data就如同类的实例。下面我们通过一个简单的例子来演示这两个属性的使用:

new Ext.Component({
      ...
      tpl: '{name} is {age} years old and lives in {location}',
      data: {
         age: 26,
         location: 'Italy',
         name: 'Mario'
     }
 });

Html代码

<div ...> Mario is 26 years old and lives in Italy </div>

和html属性一样,我们可以通过ext组件的update方法来改变组件的内容,所不同的是,这次传递的参数是data对象而不是html字符串:

var summary = new Ext.Component({
     ...
      tpl: '{name} is {age} years old and lives in {location}',
      data: {
         age: 26,
         location: 'Italy',
         name: 'Mario'
     } 
});  
new Ext.button.Button({
     ...
      handler: function() {
         summary.update({
             age: 7,
             location: 'Japan',
             name: 'Aimee'
         });
     }
 });

XTemplates 拥有丰富而强大的语法,它比精确的数据有更好的表现。完整的template描述超出了本文的范畴,但下面的例子可以让人领会到template的功能,它颜色了如何通过数组数据来生成html列表:

new Ext.Component({
     ...
      data: ['London', 'Paris', 'Moscow', 'New York', 'Tokyo'],
      tpl: [
         '<ul>',
             '<tpl for=".">',
                 '<li>{.}</li>',
             '</tpl>',
         '</ul>'
     ]
 });

生成的html如下:

<div ...> 
    <ul> 
        <li>London</li> 
        <li>Paris</li> 
        <li>Moscow</li> 
        <li>New York</li> 
        <li>Tokyo</li> 
    </ul> 
</div>

注意:现在

    依然包含在Ext组件的主元素
    中, 如果我们想去掉
    可以用前面提到的autoEl配置项将Ext组件的主元素转换为
      ,并去掉模板中的
        元素:

new Ext.Component({ 
    ... 
    autoEl: 'ul', 
    data: ['London', 'Paris', 'Moscow', 'New York', 'Tokyo'], 
    tpl: [ 
        '<tpl for=".">', 
            '<li>{.}</li>', 
        '</tpl>' 
    ] 
});

转码 (HTML Encoding)
默认情况下,XTemplates不会对html的值进行转码(类似直接将值拼接到html中--译者注);但是我们在XTemplates中使用Ext.util.Format.htmlEncode就可以轻易将值进行转码:

new Ext.Component({ 
    ... 
    tpl: '<b>Email:</b> {email:htmlEncode}', 
    data: { 
        email: 'John <john@example.com>' 
    } 
});

targetEl 属性
Ext的大部分复杂组件如panels和windows, 通过html属性和tpl属性配置的html内容并没有直接注入到Ext组件的el中,这样做是为了防止它们的header和toolbar等元素被body元素替换掉:

new Ext.panel.Panel({ 
    ... 
    bodyPadding: 10, 
    title: 'Title', 
    tpl: 'Some <b>{lang}</b> content', 
    data: { 
        lang: 'HTML' 
    } 
});

这里渲染的html元素就被称做targetEl。稍后我们将看到如何在自定义组件中改变targetEl。

需要说明的是autoEl依然承担着配置组件外部el的功能,它不受targetEl的影响。

小结
现在我们已经了解了如何使用Ext组件创建简单的html页面:

  1. 使用autoEl属性配置最外层的html元素;
  2. 使用html属性配置简单的html内容;
  3. 使用tpl + data来生成动态html内容。
  4. 但是,创建html页面只是工作的第一步,下面三节我们将讲解Ext组件之间交互常用的技术。

作者:Skirtle's Den
原文:http://skirtlesden.com/articles/html-and-extjs-components

译者:lic0112
译文:http://lic0112.iteye.com/blog/2154771