Ext JS 6学习文档-第6章-高级组件
Ext JS 6学习文档-第6章-高级组件
高级组件
本章涵盖了高级组件,比如 tree 和 data view。它将为读者呈现一个示例项目为 图片浏览器,它使用 tree 和 data view 组件。以下是本章将要讨论的主题:
- Trees
- Data views
- 拖放
- 图片浏览器 — 一个示例项目
本章的主要目标是探索 tree panel 和 data view 并且使用他们来构建一个示例项目图片浏览器。图片浏览器的最终展示效果如下图。
这个项目中的最重要的组件是 tree panel 和 data view 。本项目中使用的组件和概念有:
- tree panel
- Data views
- Model
- store 和 rest 代理
- 容器和布局
- 引用
- 事件处理
- 过滤
除了 tree panel 和 data view 你已经在之前的章节中学习了所有的我们目前已用到的知识。所以在本章中,我们首先学习 tree panel 和 data view。
tree panel
这在 ExtJS 中是一个非常强大且常用的组件,你可以使用它构建任意类型的树。一个 tree panel 是一个树形结构的具有层次化数据的UI。
它和 Ext.grid.Panel 相似, Ext.tree.Panel 也继承自Ext.panel.Table 。所以,它也是支持多列的。
和 grid panel 不同的是,tree panel 需要一个 tree store (Ext.Store.TreeStore)。 tree store 具有一些 tree panel 的功能所需使用的特殊的属性。
基本的 tree
我们来用一个简单的例子演示。tree panel 至少需要一个 tree store 来提供数据。我们首先来创建 tree store 并硬编码内置数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
text: 'Continents',
children: [{
text: 'Antarctica',
leaf: true
}, {
text: 'South America',
expanded: true,
children: [{
text: 'Brazil',
leaf: true
}, {
text: 'Chile',
leaf: true
}]
}, {
text: 'Asia',
expanded: true,
children: [{
text: 'India',
leaf: true
},{
text: 'China',
leaf: true
}]
}, {
text: 'Africa',
leaf: true
}]
}
});
|
接着继续创建 Ext.tree.Panel :
1
2
3
4
5
6
7
8
|
Ext.create('Ext.tree.Panel', {
title: 'Basic Tree',
width: 200,
height: 450,
store: store,
rootVisible: true,
renderTo: Ext.getBody()
});
|
下列截图为以上代码的输出结果:
现在,我们创建一个高级点的树,它是可以拖拽的。同时还需要用到 tree panel 和 tree store 的一些额外选项。拖拽只需要添加一个插件叫做treeviewdragdrop 。如以下代码所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
text: 'Continents',
checked: false,
children: [{
text: 'Antarctica',
leaf: true ,
checked: false
},{
text: 'South America',
expanded: false,
checked: true,
children: [{
text: 'Chile',
leaf: true,
checked: true
}]
},{
text: 'Asia',
expanded: true,
checked: true,
children: [{
text: 'India',
leaf: true,
checked: true
},{
text: 'China',
leaf: true,
checked: true
}]
},{
text: 'Africa',
leaf: true,
checked: true
}]
}
});
Ext.create('Ext.tree.Panel', {
title: 'Basic Tree',
width: 200,
height: 450,
store: store,
rootVisible: true,
useArrows: true,
lines: false,
renderTo: Ext.getBody(),
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop',
containerScroll: true
}
}
});
|
如以下截图所示的输出。我把节点 South America 拖拽至 Asia 节点之下:
tree grid
你可以将多个列添加到 tree ,同时也能创建 tree grid 。默认 tree 包含一列,用的是 tree store 中节点的文本字段。
在这个 store 中,你可以看到在每个节点上除了节点名称,还添加了一些其他的字段,这些字段用于在 tree panel 的列展示上。tree grid 的功能有例如 列调整,排序,过滤等等,以下是代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
text: 'Continents',
children: [{
name: 'Antarctica',
population: 0,
area: 14,
leaf: true
},{
name: 'South America',
population: 385 ,
area: 17.84,
expanded: false,
children: [{
name: 'Chile',
population: 18,
area: 0.7,
leaf: true,
}]
},{
name: 'Asia',
expanded: true,
population: 4164,
area: 44.57,
children: [{
name: 'India',
leaf: true,
population: 1210,
area: 3.2
},{
name: 'China',
leaf: true,
population: 1357,
area: 9.5
}]
},{
name: 'Africa',
leaf: true,
population: 1110,
area: 30
}]
}
});
|
以下的 grid 和上面的 tree panel 差不多一样,只是添加为多列了,这个 xtyp treecolumn 提供缩进和文件夹结构。像一个正常的 grid 一样,tree grid 的列可以是任意类型的例如 checkbox,picture,button,URL 等等。
默认列大小是可调整的,如果需要你也可以固定它的宽度。看下面的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
Ext.create('Ext.tree.Panel', {
title: 'Tree Grid',
width: 500,
height: 450,
store: store,
rootVisible: false,
useArrows: true,
lines: false,
scope: this,
renderTo: Ext.getBody(),
columns: [{
xtype: 'treecolumn',
text: 'Name',
flex: 1,
sortable: true,
dataIndex: 'name'
} , {
text: 'Population (millons)',
sortable: true,
width: 150,
dataIndex: 'population'
} , {
text: 'Area (millons km^2)',
width: 150,
sortable: true,
dataIndex: 'area'
}]
});
|
这是上面 Tree Grid 的输出结果:
Data views
Ext.view.View (xtype:dataview) 一个现实数据的自定义模板。你需要提供自定义的模板和数据源(store)。模板应该使用 Ext.XTemplate 。
data view 提供了内置的事件,例如 click,double-click,mouseover,mouseout,等等。
首先我们创建一个简单的 model 名为 Person ,还需要创建一个 store 并持有 Person 的列表,如以下代码所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
Ext.define('Person', {
extend : 'Ext.data.Model',
fields : [ {
name : 'name',
type : 'string'
}, {
name : 'age',
type : 'int'
}, {
name : 'gender',
type : 'int'
} ]
});
Ext.create('Ext.data.Store', {
id : 'employees',
model : 'Person',
data : [{
name : 'Mike',
age : 22,
gender : 0
},{
name : 'Woo',
age : 32,
gender : 1
},{
name : 'John',
age : 33,
gender : 1
},{
name : 'Kalai',
age : 25,
gender : 0
}]
});
|
然后我们要来创建这个模板。下列模板使用 HTML 的 table 元素来呈现自定义格式的数据。
在模板中使用一个 model 的字段时,你可以使用花括号包括字段名的方式来使用它,例如:{fieldname}
XTemplate 支持有条件的展现和 if 语句,如以下代码所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
var empTpl = new Ext.XTemplate(
'<tpl for=".">',
'<div style="margin-bottom: 10px;" class="data-view">',
'<table style="width:100%">',
'<tr>',
'<td style="font-size: 100px;width:100px;" rowspan="3"><i class="fa fa-user"></i></td>',
'<td>Name: {name}< /td>',
'</tr>',
'<tr>',
'<td>Age:{age}< /td>',
'</tr>',
'<tr>',
'<td>Gender: <tpl if="gender == 1">',
'<i class="fa fa-mars"></i>',
'<tpl else>',
'<i class="fa fa-venus"></i>',
'</tpl></td>',
'</tr></table> ',
'</div>',
'</tpl>'
) ;
|
看上面的例子,我使用了 awesome 字体图标的样式。你需要添加下列代码到你的 HTML 文件才行:
1
|
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font- awesome/4.3.0/css/font-awesome.min.css">
|
一下代码创建了一个 data view,并且它指定了使用的数据源 store ,template 和 itemSelector :
1
2
3
4
5
6
7
8
9
10
11
|
Ext.create('Ext.view.View', {
store : Ext.getStore('employees'),
tpl : empTpl,
itemSelector : 'div.data-view',
renderTo : Ext.getBody(),
listeners : {
itemclick : function(node, rec, item, index, e) {
alert(rec.data.name);
}
}
});
|
itemSelector 是一个必须的简单 CSS 选择器。这里 itemSelector 是应用于在 template 中的 HTML ,就是使用 data-view 类的 div 标签,最终根据这个模板,你在 data view 中选择的每一个 item ,就是这样一个 div 标签,设置了 itemSelector 属性,data view 会知道如何处理这些节点,itemSelector 是用于将 DOM 节点映射到 records 。
你可以监听的事件例如 click ,double-click ,等等,以上代码已经添加了监听,下列是输出结果:
图片浏览器 – 一个示例项目
惯例,我们将用一个示例项目来回顾本章所学,下面是示例项目的最终设计效果:
通过查看这个设计,你会看到我们使用的最重要的组件就是 tree panel 和 data view 。它们如何使用和一些概念已经在本章的前面部分提及。
我们看看, 项目的目录结构。
下列视图代码是本项目的重要部分。这个视图呈现了应用中大部分可视组件。它使用 tree panle 和 data view :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
Ext.define('PE.view.pics.Pics', {
extend : 'Ext.panel.Panel',
/* Marks these are required classes to be to loaded before loading this view */
requires : [ 'PE.view.pics.PicsController' ],
xtype : 'app-pics',
controller : 'pics',
items : [ {
xtype : 'container',
layout : 'hbox',
cls : 'pics-list',
items : [ {
xtype : 'treepanel',
width : 200,
height : '100%',
store : 'albums',
border : true,
useArrows : true,
cls : 'tree',
rootVisible : false,
listeners : {
itemdblclick : 'onNodeSelect'
},
dockedItems : [ {
xtype : 'toolbar',
dock : 'top',
ui : 'footer',
items : [{
xtype : 'component',
flex : 1
},{
xtype : 'button',
text : 'Upload',
cls : 'btn-blue'
}]
}]
},{
xtype : 'dataview',
reference : 'picsList',
cls : 'pics-list-content',
store : 'pics',
tpl : [
'<tpl for=".">',
'<div class="thumb"><img src="{url}" title=""></div>',
'</tpl>'
],
multiSelect : true,
minHeight : 400,
flex : 1,
trackOver : true,
overItemCls : 'x-item-over',
itemSelector : 'div.thumb',
emptyText : 'No images to display'
}]
}]
});
|
控制器 ViewController 里处理了 tree panel 的 itemdblclick 事件,只显示所选择节点下的图片。
还有一个 upload 按钮的 click 事件,这里是未处理的。额,这是你的作业啦。看看下列代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
Ext.define('PE.view.pics.PicsController', {
extend : 'Ext.app.ViewController',
alias : 'controller.pics',
views : [ 'PE.view.pics.Pics' ],
requires : [ 'PE.store.Pics', 'PE.store.Albums' ],
onNodeSelect : function(node, rec, item, index, e){
var albums = [];
albums.push(rec.id);
rec.childNodes.forEach(function(item) {
albums.push(item.id);
});
Ext.getStore('pics').filter({
property : 'albumId',
operator : 'in',
value : albums
});
}
});
|
Model 和 Store 的代码在这儿。
- 注意:当你不指定 model 的字段类型时,将会自动猜测类型。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
Ext.define('Pic', {
extend : 'Ext.data.Model',
fields : [ 'id', 'url', 'albumId' ]
});
Ext.define('PE.store.Pics', {
extend : 'Ext.data.Store',
storeId : 'pics',
model : 'Pic',
proxy : {
type : 'rest',
url : 'pics', // URL that will load data with respect to start and limit params
reader : {
type : 'json'
}
}
});
Ext.create('PE.store.Pics').load();
Ext.define('PE.store.Albums', {
extend : 'Ext.data.TreeStore',
storeId : 'albums',
root : {
expanded : true,
children : [ {
id : 100,
text : ' California',
expanded : true,
children : [ {
id : 600,
text : ' Big Sur',
leaf : true
}, {
id : 500,
text : ' Yosemite',
leaf : true
}]
}, {
id : 400,
text : ' Arizona',
expanded : true,
children : [ {
id : 300,
text : ' Horseshoe bend',
leaf : true
}]
}, {
id : 200,
text : ' Home',
leaf : true
}, {
id : 700,
text : ' India',
expanded : true,
children : [ {
id : 800,
text : ' Ooty',
leaf : true
}, {
id : 900,
text : ' Chennai',
leaf : true
}, {
id : 1000,
text : ' Munnar',
leaf : true
} ]
} ]
}
});
Ext.create('PE.store.Albums');
|
我是用的 Go 语言为此项目写的 REST API 。完整可用的代码在这里 https://github.com/ananddayalan/extjs-byexample-picture-explorer
图片浏览器这个示例是一个非常简单并用来学习 tree panel 和 data view 使用是很合适的。也可以通过添加更多功能来改进这个例子。例如如何通过拖拽将图片从一个相册移动到另一个相册中。 我会留给你作为一个编码的练习,但在这里,我给你简要的概述一下拖拽功能,这将帮助你在此项目中添加拖拽功能。
拖拽
任意元素或组件都能支持拖拽。使用拖拽有三个重要的事情:
- 配置 item 为可拖拽的Configure the items as draggable
- 创建放置目标
- 完成放置目标
配置 item 为可拖拽的
想要拖拽一个 item ,你需要为每一个元素创建 Ext.dd.DD 实例。
查看下列代码,通过创建 Ext.dd.DD 让所有使用 pics 类的 div 元素成为可拖拽的:
1
2
3
4
5
6
|
// Configure the pics as draggable var pics = Ext.get('pics').select('div');
Ext.each(pics.elements, function(el) {
var dd = Ext.create('Ext.dd.DD', el, ' picsDDGroup', {
isTarget : false
});
});
|
创建放置目标
使用 Ext.dd.DDTarget 创建放置容器。以下代码为所有的使用 album 类的 div 元素创建放置目标:
1
2
3
4
5
|
var albums = Ext.get('album').select('div');
Ext.each(albums.elements, function(el) {
var albumDDTarget = Ext.create('Ext.dd.DDTarget', el,
'picsDDGroup');
});
|
完成放置目标
当一个可拖拽项放置到一个放置容器,我们需要从这个 item 的源位置将它移动到目标位置。这通过覆盖 DD 的 onDragDrop 方法来实现。看一看下列代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
var overrides = {
onDragDrop : function(evtObj, targetElId) {
var dropEl = Ext.get(targetElId);
if (this.el.dom.parentNode.id != targetElId) {
dropEl.appendChild(this.el);
this.onDragOut(evtObj, targetElId);
this.el.dom.style.position = '';
this.el.dom.style.top = '';
this.el.dom.style.left = '';
} else {
this.onInvalidDrop();
}
},
onInvalidDrop : function() {
this.invalidDrop = true;
}
};
|
因为 DD 元素已经是实例了,重写的方法需要应用 Ext.apply(dd, overrides) ,如以下代码所示:
1
2
3
4
5
6
7
8
|
var albums = Ext.get('album').select('div');
var pics = Ext.get('pics').select('div');
Ext.each(pics.elements, function(el) {
var dd = Ext.create('Ext.dd.DD', el, ' picsDDGroup', {
isTarget : false
});
Ext.apply(dd, overrides);
});
|
总结
在本章中,你学习到如何使用拖拽功能。我们也看了几个高级组件:tree panel 和 data view。最后结合所学创建了一个示例项目。
Ext JS 6学习文档-第6章-高级组件的更多相关文章
- Ext JS 6学习文档-第5章-表格组件(grid)
Ext JS 6学习文档-第5章-表格组件(grid) 使用 Grid 本章将探索 Ext JS 的高级组件 grid .还将使用它帮助读者建立一个功能齐全的公司目录.本章介绍下列几点主题: 基本的 ...
- Ext JS 6学习文档-第3章-基础组件
Ext JS 6学习文档-第3章-基础组件 基础组件 在本章中,你将学习到一些 Ext JS 基础组件的使用.同时我们会结合所学创建一个小项目.这一章我们将学习以下知识点: 熟悉基本的组件 – 按钮, ...
- Ext JS 6学习文档-第8章-主题和响应式设计
Ext JS 6学习文档-第8章-主题和响应式设计 主题和响应式设计 本章重点在 ExtJS 应用的主题和响应式设计.主要有以下几点内容: SASS 介绍和入门 主题 响应式设计 SASS 介绍和入门 ...
- Ext JS 6学习文档-第7章-图表
Ext JS 6学习文档-第7章-图表 使用图表 本章中将探索在 ExtJS 中使用不同类型的图表并使用一个名为费用分析的示例项目结束本章所学.以下是将要所学的内容: 图表类型 条形图 和 柱形图 图 ...
- Ext JS 6学习文档-第4章-数据包
Ext JS 6学习文档-第4章-数据包 数据包 本章探索 Ext JS 中处理数据可用的工具以及服务器和客户端之间的通信.在本章结束时将写一个调用 RESTful 服务的例子.下面是本章的内容: 模 ...
- Ext JS 6学习文档–第1章–ExtJS入门指南
Ext JS 入门指南 前言 本来我是打算自己写一个系列的 ExtJS 6 学习笔记的,因为 ExtJS 6 目前的中文学习资料还很少.google 搜索资料时找到了一本国外牛人写的关于 ExtJS ...
- Ext JS 6学习文档–第2章–核心概念
核心概念 在下一章我们会构建一个示例项目,而在这之前,你需要学习一些在 Ext JS 中的核心概念,这有助于你更容易理解示例项目.这一章我们将学习以下知识点: 类系统,创建和扩展类 事件 Ext JS ...
- Sencha Cmd 6 和 Ext JS 6 指南文档(部分官方文档中文翻译)
近期组织了几个程序员网友,正在翻译一部分官方的Sencha Cmd 6 和 Ext JS 6 指南文档. 眼下还没翻译完,大家能够先看看 Sencha Cmd 6 和 Ext JS 6 指南文档 ( ...
- Prism 4 文档 ---第6章 高级MVVM场景
在上一章中描述了如何通过将UI,表现逻辑,业务逻辑分别放到三个单独的类中(View,View Model,Model),实现这些类之间的交互(通过数据绑定,命令以及数据验证接口)以及实现一个策 ...
随机推荐
- iPhone 横竖屏切换,全屏播放的三种方式
1. 调用系统自带的强制屏幕旋转不过还得在AppDelegate中重写下面方法 - (UIInterfaceOrientationMask)application:(UIApplication *)a ...
- BZOJ2298: [HAOI2011]problem a(带权区间覆盖DP)
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1747 Solved: 876[Submit][Status][Discuss] Descripti ...
- free -g 说明
free -g 说明: free -g -/+ buffers/cache 说明: buffer 写缓存,表示脏数据写入磁盘之前缓存一段时间,可以释放.sync命令可以把buffer强制写入硬盘 ca ...
- CentOS 6.8安装Ceph
机器规划 IP 主机名 角色 10.101.0.1 ceph01 mon admin mds 10.101.0.2 ceph02 ods 10.101.0.3 ceph03 ods 10.101.0. ...
- Python记录键盘鼠标敲击次数
Idea 作为一个每天有一半时间都在电脑旁的人,无时无刻不在敲击着键盘,点击着鼠标.有一天,我突然很想知道在一天的时间内,在我轻盈的指法下面,键盘被我狂敲了多少下,鼠标又被我点击了多少次.甚至更具体一 ...
- Vue路由钩子 afterEach beforeEach区别
vue-router作为vue里面最基础的服务,学习一段时间,对遇到的需求进行一些总结 使用vue-cli作为开发前提 vue-router已经配置好了 路由写法 routes: [ { path ...
- 企业IT架构转型之道 读后感
放假三天,用部分时间阅读了企业IT架构转型之道这本书.第一遍潦草读完,就感觉收益颇多.这本书值得多读几遍,适合精度. 作为银行IT开发人员,在央企IT成本部门的大背景下,开发过程中遇到的诸多疑惑.困惑 ...
- itertools.groupby()分组字典列表
## itertools.groupby()分组字典列表数据 from operator import itemgetter from itertools import groupby student ...
- 微信小程序快速转成百度小程序的方法
1.安装Node.js(>8.5.0)https://nodejs.org/ npm升级到最新版本的方法:npm install -g npm自动更新到最新版本 2.配置cnpm:在命令行中输入 ...
- PHP基础3--文件加载-错误处理
主要: 1-文件加载 2-错误处理 文件加载 文件加载语句 1) 4个文件加载语句:include, require, include_once, require_once 2) 使用形式 ...