投放本站广告请联系:
extjscn#126.com
表单字段自动从本地化类获取标签文本
在《Ext JS 6.2实战》一书中,定义了用于实现应用程序本地化的I18N类,而在定义表单字段时,是直接使用I18N来引用表单字段的标签文本的,当表单字段比较多,项目的表单也比较多的时候,老是这样引用,也挺麻烦的,因而,最好的方式是让字段自己根据name配置项定义的名称去I18N取标签文本。本文要做的就是要实现这个。
要实现自动获取标签文本,需要解决的问题主要是以下两个:
- 怎么修改才能涵盖所有的字段,不需要修改每一个字段的定义
- 如何获取标签文本
第一个问题好解决,因为表单字段有一个基类Ext.form.field.Base,从这个类入手就行了。
第二问题需要解决的就是如何根据name去获取标签文本。在I18N的定义中,对于表单字段的定义的标签文本定义,都添加了一个“xxxxModel”的名称来管理标签文本,以避免出现名称相同而标签文本表示不同的问题。要让字段自动获取到标签文本,就必须让字段知道这个“xxxxModel”的名称。要实现这个,挺简单的,为字段添加一个配置项来指定这个名称就好了。
基本思路清晰后,就可以动手来实现了。首先要做的是在《ExtJS 6:Visual Studio Code、创建包和权限管理 》一文中实现的公共包中,在overrides文件夹添加文件夹form\field,并添加一个名为Base.js的脚本文件。脚本添加后,加入以下代码:
Ext.define('Common.overrides.form.field.Base', { override: 'Ext.form.field.Base', entityName: null, });
代码中,entityName就是新增的用来获取标签文本的实体名称。
为了能在字段初始化前完成标签文本的设置,我们需要重写Base字段的initComponent方法。把Ext.form.field.Base的initComponent方法复制到类中,然后在callParent方法前添加以下代码:
var me = this, entity= me.entityName, name = me.name, label; if (entity) { label = I18N['model'][entity][name]; if(me.isCheckbox || me.isRadio){ me.boxLabel = label; }else{ me.fieldLabel = label; } } .......
代码需要在callParent方法前执行是因为在调用callParent方法后,组件已经初始化完成了,不能再通过直接赋值的方式来修改标签文本了。
代码中,先判断是否定义了实体名称,如果没有,则不设置标签文本,如果有,则从本地化文件中获取标签文本,并进行赋值操作。这里要注意的是,复选字段和单选字段是在boxLabel配置项中设置标签文本的,因而这里需要通过isCheckbox属性和isRadio属性来判断字段是复选字段还是单选字段,如果是,则将标签文本赋值给boxLabel,如果不是,则将标签文本赋值给fieldLabel。
为了更好的在本地化文件中结构化标签文本,在这里特意实体定义在model对象里。
下面来验证下该方法是否可行。在app文件夹下,新建一个名为locale的文件夹并添加一个名为zh_CN.js的脚本文件。在文件内添加以下代码:
Ext.define('PackageTest.locale.zh_CN',{ override: 'Common.locale.Locale', statics: { model:{ login:{ name:'名称', password: '密码', remberMe: '记住我' } } } });
在代码中,定义了一个名为login的实体,并定义了3个标签。
在app\view1\Main.js的items内添加以下代码:
items:[ { xtype: 'form', defaults:{ entityName: 'login' }, items:[ { xtype: 'textfield', name: 'name'}, { xtype: 'textfield', name: 'password', inputType: 'password'}, { xtype: 'checkboxfield', name: 'remberMe'} ] } ]
在代码中,定义了一个表单面板。配置项defaults为表单中的每个字段添加entityName配置项,实体的名称为login,也就是将会从本地化类的login实体获取标签文本。
代码完成后,打开app.js文件,将requires配置项修改为以下代码:
requires: [ 'Common.overrides.*', 'Common.locale.*', 'PackageTest.locale.*', 'Common.util.*', 'PackageTest.view.main.Main' ],
在代码中,先引用了公共包中的重写类,再引用本地化的基类,之后是具体的本地化类、公共包的功能类和主视图。
代码完成后,在终端窗口执行“sencha app refresh”命令刷新bootstrap.json,将新增的类添加到加载脚本中。这里不需要使用build命令是因为添加的类并没有对应的样式,不需要刷新样式文件,只需要刷新类的加载就行了。
在浏览器打开测试项目,可看见以下的视图:
从图中可以看到,字段已经成功获取到所需的标签文本了。这说明Common.overrides.form.field.Base已经正确运行了,正是我们所需的效果。
我们延伸一下,是否网格的列标题也可以使用这种方式来实现呢?这个也是可行的,有兴趣,可以自己研究下。
本文本的源代码:https://gitee.com/tianxiaode/PackageTest/blob/master/Readme.md
作者:黄灯桥
原文:http://blog.csdn.net/tianxiaode/article/details/79514979
- 要发表评论,请先登录