【翻译】Ext JS最新技巧——2015-8-11
原文:Top Support Tips
Seth Lemmons:使用棒极了的Awesome Font
Ext JS 6附带了一个新的海卫一主题,可以使用Font Awesome字体作为背景图像的图标。不过,你知道如何通过“iconCls”和“glyph”来使用哪些相同的图标(以及更多来自于广泛的Font Awesome库)吗?
使用海卫一主题的时候
可以在诸如Ext.panel.Panel、Ext.menu.Item、Ext.button.Button等等组件中使用iconCls来设置Font Awesome字体为图标,语法如下:
// use ‘x-fa’ to add set the font family to Font Awesome
// then use “fa-{iconName}” to set the icon itself
iconCls: ‘x-fa fa-star’ // the icon will be the Star icon from Font Awesome
对于组件的“glyph”配置项,语法如下:
glyph: ‘xf005@FontAwesome’ // using the unicode “f0005” for Star
所有的Font Awesome图标都可以在Font Awesome网站内找到。
注意:“glyph”和“iconCls”配置项是互斥的。“glyph”配置项是在Ext JS 4.2中加入的,主要是解决EI6或7不支持伪元素这种情况。我们建议使用“iconCls”,而不是“glphy”,原因是Ext JS 5以上版本(只支持IE 8以上版本)所支持的浏览器都已经支持伪元素。最现代的图标字体已经都会有一套CSS规则使用伪元素来将图标应用到元素。
对于Ext.Img组件,可以通过使用autoEl配置项来封装元素,兵使用cls或glyph来实现:
Ext.create({
xtype: 'image',
autoEl: 'div',
cls: 'x-fa fa-star',
//glyph: 'xf005@FontAwesome',
alt: 'star',
style: {
fontSize: '36px',
lineHeight: '36px'
},
height: 36,
width: 36
});
注意:对于Image的配置项,需要使用cls来代替iconCls。
不使用海卫一主题的时候
如果不使用海卫一主题,但又想在组件中使用Font Awesome图标,可以在Sencha Cmd创建的应用程序中加入Font Awesome包。要实现这个,编辑“应用程序根目录/app.json”文件,在requires数组内加入以下代码:
"requires": [
"font-awesome"
],
这样就可以像使用海卫一主题那样直接在组件中使用iconCls配置项了。
Pictos图标
还可以在app.json文件中通过请求Picto来使用Picto图标集:
"requires": [
"font-pictos"
],
请求后,就可以使用以下iconCls语法来使用Picto库的图标了:
// pictos-{iconName} is used to set a named icon from the Pictos icon set
iconCls: 'pictos pictos-home'
要了解Picto图标的对应信息,可以查看Sencha字体包指南。
查看主题指南可以了解更多有关海卫一主题以及字体图标的信息。
Joel Watson:保存关联数据的另一选项
在Ext JS 5应用程序中使用关联的时候,有许多方式可以用来保存关联的数据。无论是喜欢保存每一个单独的个体模型实例、创建一个自定义的Ext.data.writer.Writer实现,还是使用Ext.data.Session来创建批处理,Ext JS都提供了极大的灵活性以便你以最适合你的应用程序的的方式处理数据。
不过,在Ext JS 5中, Ext.data.writer.Writer有几个新的特性为你提供了一种新选择:allDataOptions和partialDataOptions。
这些配置项允许你在模型数据将要被发送到服务器时,去定义传递给Ext.data.Model的getData方法的选项。allDataOptions用于phantom(新)记录(或在writeAllFields为true的时候),而partialDataOptions则用于其他方面(或writeAllFields为false的时候)。
这样对关联数据有什么好处呢?
下面来看两个实体,User和Address:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: ['firstName', 'lastName', 'age', {
name: 'addressId',
reference: 'Address',
unique: true
}],
...
});
Ext.define('Address', {
extend: 'Ext.data.Model',
fields: ['street', 'city', 'state', 'postalCode']
});
在示例中,User与Address具有一对一关联,因而在保存User的时候(无论是创建一个新用户还是保存已修改过的已有用户),同样需要在同一请求中发送任何关联的Address数据。
在Ext JS 4,处理这一情况需要通过创建自定义的Ext.data.writer.Writer来扩展getRecordData方法以调用Ext.data.Model.getAssociatedData并添加关联数据到请求数据中。虽然该方式在Ext JS 5中也能很好的工作,但可以利用allDataOptions和partialDataOptions来完成相同的事情,不过需要保存几行代码:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [...],
proxy: {
type: 'ajax',
url: 'user.json’,
writer: {
type: 'json',
allDataOptions: {
persist: true,
associated: true
},
partialDataOptions: {
changes: false,
critical: true,
associated: true
}
}
}
});
在allDataOptions配置项,指定了新建的User模型数据在发送到服务器前的预处理方式:
persist: true ->只发送持续性字段(该属性默认值为true)。
associated: true ->包含关联数据
对于partialDataOptions,原理是一样的,用来指定已存在的用户模型数据发送到服务器前的预处理方式:
changes: true -> 只包含修改过的字段(默认)
critical: true -> 始终包含“关键”字段,而不管是否已被更改(默认)
associated: true -> 包含关联数据
当然,可以根据应用程序的需要调整这些配置项。不过,问题的关键是,在应用程序内创建或更新用户时,发送到服务器的请求将包含任何关联的数据,这太棒了。
有关详细信息,请查看Fiddle中User和Address模型的创建和更新示例。
Joel Watson:在Ext JS 5中使用模型的Ids
在Ext JS 5,一个相当大的变化是id的生成。在Ext JS 4,默认的id的生成器不会根据idProperty自动去生成值,例如,简单的用户模型示例:
Ext.define('Fiddle.model.User', {
extend: 'Ext.data.Model',
fields: ['firstName', 'lastName', 'age'],
proxy: {
type: 'rest',
url: 'user.json'
}
});
// create a new User
var user = new Fiddle.model.User({
firstName: 'John',
lastName: 'Doe',
age: 52
});
user.save();
在调用save发送请求到服务器的时候,会看到如下请求:
{
age: 52,
firstName: "John",
lastName: "Doe"
}
然而,在Ext JS 5,如果未提供id值,默认的id生成器会根据idProperty生成一个值,对于以上示例代码,处理结果会不同:
{
id: "User-1",
age: 52,
firstName: "John",
lastName: "Doe"
}
要注意,id(idProperty的默认值)现在被包含在请求中。在某些情况下,开发人员可能会在服务器端代码中依赖Ext JS 4的行为来确定如何处理传入的请求,在这种情况下,在Ext JS 5中的这种改变可能会引起一些冲突。
幸运的是,有许多选项可以用来处理(或左右)这种改变。
ID生成器
第一个选项(并且可能是最好的一个)是使用Ext JS中的id生成器,例如,使用Ext.data.identifier.Negative,该id生成器会产生连续的、值为负数的客户端id值。在大多数的服务器端,id值是基于整数并是顺序增加的,而由Ext.data.identifier.Negative产生的临时id值,则很容易辨析,这样,服务器代码就可以很轻松的确定这是新的还是已有的Ext JS模型数据。
以上使用负数标识符的示例的处理结果可能会像以下代码:
{
id: -1,
age: 52,
firstName: "John",
lastName: "Doe"
}
示例:使用负数标识符:https://fiddle.sencha.com/#fiddle/p03
当然,如果这个都不能满足你的需求,你可以通过扩展Ext.data.identifier.Generator来创建自己的生成器。
clientIdProperty
如果使用id生成器不符合应用程序的需求,另一个选择就是使用已被添加到Ext.data.writer.Writer的clientIdProperty配置项。使用该配置项,就可以在创建一个新记录并发送数据到服务器时指定一个名字作为idProperty值的关键字:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: ['firstName', 'lastName', 'age'],
proxy: {
type: 'rest',
url: 'user.json',
writer: {
type: 'json',
clientIdProperty: 'userId'
}
}
})
在保存用户实例的时候,发送到服务器的数据会类似以下代码:
{
"userId": "User-1",
"firstName": "John",
"lastName": "Doe",
"age": 52
}
对于现有的服务器代码依赖于id来标识新记录的方式,该方式可保持现状,不需要修改逻辑。
示例:使用clientIdProperty:https://fiddle.sencha.com/#fiddle/p02
transform()
最后一个选择是在代理的writer中指定一个自定义的transform方法。transform方法需要两个参数“data”和“request”,并预期要返回发送到服务器的数据对象:
writer: {
type: 'json',
transform: function(data, request) {
// do any data transformations here
// ...
// return the data object that should be sent to server
return data;
}
}
使用transform,可以在发送请求之前做任何所需的数据处理(例如,移除id属性)。这三个选项,为发送到服务器的数据内容提供了最大的控制。不过,这会增加数据错误的风险,因而,使用需谨慎。
示例:使用transform:https://fiddle.sencha.com/#fiddle/p05
有关Ext JS 5中数据模型的改变和改进的更多信息,请参阅Ext JS升级指南。