DomHelper和Template动态生成html
用dom生成html元素一直是头疼的事情,以前都是听springside的教导,使用jsTemplate和Scriptaculous的组合。现在到了ext里面,我们就来看看它自己的实现。
DomHelper用来生成小片段
使用DomHelper非常灵活,超简单就可以生成各种html片段,遇到复杂情况也要依靠于它。
大概就是这么用
var list = Ext.DomHelper.append('parent', {tag: 'div', cls: 'red'});
它就是向id=parent这个元素里,添加一个div元素。
按照文档里讲的,第二个参数{}里,除了四个特殊属性以外都会复制给新生成元素的属性,这四个特殊属性是
tag,告诉我们要生成一个什么标签,div啦,span啦,诸如此类。
千万别告诉我到现在你还不知道这些html标签,中间告诉你多少次先去学学html和css啦?你飞过来的不成?
cls,指的是<div class="red"></div>这种标签中的class属性,因为class是关键字,正常情况下应该写成className,可jack说className太长了,最后就变成cls了。-_-。
他就喜欢玩这个,把dataStore写成ds,DomHelper写成dh,Element写成el,ColumnModel写成cm,SelectionModel是sm。唉,发明的专业名词缩写好多呀。
children,用来指定子节点,它的值是一个数组,里边包含了更多节点。
html,对应innerHTML,觉得用children描述太烦琐,直接告诉节点里边的html内容也是一样。
DomHelper除了append还有几个方法,指定将新节点添加到什么位置。
为了比对效果,先放一个初始页面。
原始的html是这样的。一个div下有4个节点,其中第三个子节点下还有自己的子节点。
<div id="parent" style="border: 1px solid black;padding: 5px;margin: 5px;background: lightgray;">
<p id="child1">child1</p>
<p id="child2">child2</p>
<div id="child3">
<p id="child5">inner child</p>
</div>
<p id="child3">child4</p>
</div>
append是将新节点放到指定节点的最后。
Ext.DomHelper.append('parent', {tag: 'p', cls: 'red', html: 'append child'});
insertBefore,新节点插入到指定节点前面。
Ext.DomHelper.insertBefore('parent', {tag: 'p', cls: 'red', html: 'insert before child'})
insertAfter,新节点插入到指定节点后面。
Ext.DomHelper.insertAfter('parent', {tag: 'p', cls: 'red', html: 'insert before child'})
overwrite,会替换指定节点的innerHTML内容。
Ext.DomHelper.overwrite('child3', {tag: 'p', cls: 'red', html: 'overwrite child'})
闲来无聊,也看一看children这个属性的用法。
Ext.DomHelper.append('parent', {
tag: 'ul',
style: 'background: white;list-style-type: disc;padding: 20px;',
children: [
{tag: 'li', html: 'li1'},
{tag: 'li', html: 'li2'},
{tag: 'li', html: 'li3'}
]
});
这样就在parent里添加了一个ul标签,ul里包含三个li。呵呵~炫啊。
代码见lingo-sample/1.1.1/08-03.html和lingo-sample/2.0/08-03.html。
8.3.2. 批量生成还是需要Template模板
场景模拟:目前有三男两女的json数据,要输出成html显示出来。
var data = [
['1','male','name1','descn1'],
['2','female','name2','descn2'],
['3','male','name3','descn3'],
['4','female','name4','descn4'],
['5','male','name5','descn5']
];
照搬grid时的测试数据呢,嘿嘿。只不过这次我们用的不再是ds,cm,grid的方式解析输出,而是用模板自己定义输出的格式。
首先要定义一个模板
var t = new Ext.Template(
'<tr>',
'<td>{0}</td>',
'<td>{1}</td>',
'<td>{2}</td>',
'<td>{3}</td>',
'</tr>'
);
t.compile();
索引从0开始,一共4个元素。然后在用的时候,这样子。
for (var i = 0; i < data.length; i++) {
t.append('some-element', data[]);
}
这段代码对应html中的一个表格,id="some-element"是tbody的id,我们使用模板为table增添了四行。
<table border="1">
<tbody id="some-element">
<tr>
<td>id</td>
<td>sex</td>
<td>name</td>
<td>descn</td>
</tr>
</tbody>
</table>
最终的显示结果就是包含五行数据的表格:
定义模板的时候,可以使用Ext.util.Format里的工具方法,对数据进行格式化。常用的就是trim去掉收尾空格和ellipsis(10),ellipsis判断,当字符长度超过10时,自动截断字符串并在末尾添加省略号,很常用的功能哩。
在模板里使用这些函数的话也很简单,不过我不说,你还是不知道,嘿嘿
var t = new Ext.Template(
'<tr>',
'<td>{0}</td>',
'<td>{1:trim}</td>',
'<td>{2:trim}</td>',
'<td>{3:ellipsis(10)}</td>',
'</tr>'
);
t.compile();
如此这般,冒号加函数名称就可以实现我们的愿望了。
可惜人算终不如天算,jack再神奇,也不可能考虑到所有的可能性,比如现在我们就想根据性别不同显示图片,jack怕是想破了脑袋,也想不出这种可能来,所以呢,他干脆不想了,而是给咱们留了一个自定义函数的接口。
var t = new Ext.Template(
'<tr>',
'<td>{0}</td>',
'<td>{1:this.renderSex}</td>',
'<td>{2:trim}</td>',
'<td>{3:ellipsis(10)}</td>',
'</tr>'
);
t.renderSex = function(value) {
if (value == 'male') {
return "<span style='color:red;font-weight:bold;'>红男</span><img src='user_male.png' />";
} else {
return "<span style='color:green;font-weight:bold;'>绿女</span><img src='user_female.png' />";
}
};
t.compile();
显示的红男绿女,就像我们预想的那样呈现在我们眼前了。
用dom生成html元素一直是头疼的事情,以前都是听springside的教导,使用jsTemplate和Scriptaculous的组合。现在到了ext里面,我们就来看看它自己的实现。
DomHelper用来生成小片段
使用DomHelper非常灵活,超简单就可以生成各种html片段,遇到复杂情况也要依靠于它。
大概就是这么用
var list = Ext.DomHelper.append('parent', {tag: 'div', cls: 'red'});
它就是向id=parent这个元素里,添加一个div元素。
按照文档里讲的,第二个参数{}里,除了四个特殊属性以外都会复制给新生成元素的属性,这四个特殊属性是
tag,告诉我们要生成一个什么标签,div啦,span啦,诸如此类。
千万别告诉我到现在你还不知道这些html标签,中间告诉你多少次先去学学html和css啦?你飞过来的不成?
cls,指的是<div class="red"></div>这种标签中的class属性,因为class是关键字,正常情况下应该写成className,可jack说className太长了,最后就变成cls了。-_-。
他就喜欢玩这个,把dataStore写成ds,DomHelper写成dh,Element写成el,ColumnModel写成cm,SelectionModel是sm。唉,发明的专业名词缩写好多呀。
children,用来指定子节点,它的值是一个数组,里边包含了更多节点。
html,对应innerHTML,觉得用children描述太烦琐,直接告诉节点里边的html内容也是一样。
DomHelper除了append还有几个方法,指定将新节点添加到什么位置。
为了比对效果,先放一个初始页面。
原始的html是这样的。一个div下有4个节点,其中第三个子节点下还有自己的子节点。
<div id="parent" style="border: 1px solid black;padding: 5px;margin: 5px;background: lightgray;">
<p id="child1">child1</p>
<p id="child2">child2</p>
<div id="child3">
<p id="child5">inner child</p>
</div>
<p id="child3">child4</p>
</div>
append是将新节点放到指定节点的最后。
Ext.DomHelper.append('parent', {tag: 'p', cls: 'red', html: 'append child'});
insertBefore,新节点插入到指定节点前面。
Ext.DomHelper.insertBefore('parent', {tag: 'p', cls: 'red', html: 'insert before child'})
insertAfter,新节点插入到指定节点后面。
Ext.DomHelper.insertAfter('parent', {tag: 'p', cls: 'red', html: 'insert before child'})
overwrite,会替换指定节点的innerHTML内容。
Ext.DomHelper.overwrite('child3', {tag: 'p', cls: 'red', html: 'overwrite child'})
闲来无聊,也看一看children这个属性的用法。
Ext.DomHelper.append('parent', {
tag: 'ul',
style: 'background: white;list-style-type: disc;padding: 20px;',
children: [
{tag: 'li', html: 'li1'},
{tag: 'li', html: 'li2'},
{tag: 'li', html: 'li3'}
]
});
这样就在parent里添加了一个ul标签,ul里包含三个li。呵呵~炫啊。
代码见lingo-sample/1.1.1/08-03.html和lingo-sample/2.0/08-03.html。
8.3.2. 批量生成还是需要Template模板
场景模拟:目前有三男两女的json数据,要输出成html显示出来。
var data = [
['1','male','name1','descn1'],
['2','female','name2','descn2'],
['3','male','name3','descn3'],
['4','female','name4','descn4'],
['5','male','name5','descn5']
];
照搬grid时的测试数据呢,嘿嘿。只不过这次我们用的不再是ds,cm,grid的方式解析输出,而是用模板自己定义输出的格式。
首先要定义一个模板
var t = new Ext.Template(
'<tr>',
'<td>{0}</td>',
'<td>{1}</td>',
'<td>{2}</td>',
'<td>{3}</td>',
'</tr>'
);
t.compile();
索引从0开始,一共4个元素。然后在用的时候,这样子。
for (var i = 0; i < data.length; i++) {
t.append('some-element', data[]);
}
这段代码对应html中的一个表格,id="some-element"是tbody的id,我们使用模板为table增添了四行。
<table border="1">
<tbody id="some-element">
<tr>
<td>id</td>
<td>sex</td>
<td>name</td>
<td>descn</td>
</tr>
</tbody>
</table>
最终的显示结果就是包含五行数据的表格:
定义模板的时候,可以使用Ext.util.Format里的工具方法,对数据进行格式化。常用的就是trim去掉收尾空格和ellipsis(10),ellipsis判断,当字符长度超过10时,自动截断字符串并在末尾添加省略号,很常用的功能哩。
在模板里使用这些函数的话也很简单,不过我不说,你还是不知道,嘿嘿
var t = new Ext.Template(
'<tr>',
'<td>{0}</td>',
'<td>{1:trim}</td>',
'<td>{2:trim}</td>',
'<td>{3:ellipsis(10)}</td>',
'</tr>'
);
t.compile();
如此这般,冒号加函数名称就可以实现我们的愿望了。
可惜人算终不如天算,jack再神奇,也不可能考虑到所有的可能性,比如现在我们就想根据性别不同显示图片,jack怕是想破了脑袋,也想不出这种可能来,所以呢,他干脆不想了,而是给咱们留了一个自定义函数的接口。
var t = new Ext.Template(
'<tr>',
'<td>{0}</td>',
'<td>{1:this.renderSex}</td>',
'<td>{2:trim}</td>',
'<td>{3:ellipsis(10)}</td>',
'</tr>'
);
t.renderSex = function(value) {
if (value == 'male') {
return "<span style='color:red;font-weight:bold;'>红男</span><img src='user_male.png' />";
} else {
return "<span style='color:green;font-weight:bold;'>绿女</span><img src='user_female.png' />";
}
};
t.compile();
显示的红男绿女,就像我们预想的那样呈现在我们眼前了。