在做Extjs4为前台的时候,遇到本地化的问题。通过google找到一点资料,希望记录下来以为后用。
参考内容:
Extjs4 API文档阅读(七)——本地化(Localization)
http://www.cnblogs.com/shukefrz/articles/2322932.html
以下为转载内容:
工作后干的活有点乱七八糟,被折磨死
每一段时间就要学新的语言。2011下半年是C#,2012年,轮换到了JavaScript
最近的任务是用ExtJS设计前端,这玩意强大到足以取代Silverlight,非常适合配合RESTful API使用,使用AJAX获取JSON或XML类型的数据,前端页面的生成完全不需要PHP/JSP,仅HTML+JS已经足够。这种情况下,前端可以和API所在服务端完全分离,部署在不同的服务器上,甚至前端可以放在用户本地运行
第一个任务是攻克多语言化(老大乃将这种任务扔给素人情何以堪)
网上搜索了一下,还有人专门写了插件(ext-locale-loader),但这种需要给每一自设计的页面弄一份语言拷贝的方式让余菊花一紧
后来阅读ExtJS的自带文档,发现有本地化的详细指引($EXTJS_FOLDER/docs/index.html#!/guide/localization)
一步步来就实现了ExtJS自身的UI元件在用户选择不同语言时的本地化
实现后的效果
演示页面:extlocalize.html
ExtJS语言列表RawData:languages.js(仅保留4个语言)
逻辑+UI:extlocalize.js
切换语言的逻辑其实非常简单,判断页面的传入参数(没错,静态页面也可以有参数),利用AJAX加载语言文件,然后执行语言文件中的代码,更新字符串
extlocalize.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Localization example</title> <!-- Ext Library Files --> <link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css"> <script src="ext/ext-all-debug.js"></script> <!-- App Scripts --> <script src="languages.js"></script> <script src="extlocalize.js"></script> </head> <body> <div id="languages"></div> <div id="datefield"></div> <div id="emailfield"></div> <div id="grid"></div> </body> </html>
languages.js
/** * by kuyur@kuyur.info * 2012.2.3 */ Ext.namespace('Ext.local'); Ext.local.languages = [ ['en', 'English'], ['ja', 'Japanese(日本語)'], ['zh_CN', 'Simplified Chinese(简体中文)'], ['zh_TW', 'Traditional Chinese(繁體中文)'] ];
extlocalize.js
/** * by kuyur@kuyur.info * 2012.2.3 */ Ext.Loader.setConfig({enabled: true}); Ext.Loader.setPath('Ext.ux', 'ext/examples/ux/'); Ext.require([ 'Ext.data.*', 'Ext.tip.QuickTipManager', 'Ext.form.*', 'Ext.ux.data.PagingMemoryProxy', 'Ext.grid.Panel' ]); Ext.onReady(function() { MultiLangDemo = (function() { return { init: function() { var store = Ext.create('Ext.data.ArrayStore', { fields: ['code', 'language'], data : Ext.local.languages //from languages.js }); var combo = Ext.create('Ext.form.field.ComboBox', { renderTo: 'languages', margin: '10, 0, 0, 10', store: store, displayField: 'language', queryMode: 'local', emptyText: 'Select a language...', hideLabel: true, width: 200, listeners: { select: { fn: function(cb, records) { var record = records[0]; window.location.search = Ext.urlEncode({"lang":record.get("code")}); }, scope: this } } }); var params = Ext.urlDecode(window.location.search.substring(1)); if (params.lang) { var url = Ext.util.Format.format('ext/locale/ext-lang-{0}.js', params.lang); Ext.Ajax.request({ url: url, success: this.onSuccess, failure: this.onFailure, scope: this }); // check if there's really a language with passed code var record = store.findRecord('code', params.lang, null, null, null, true); // if language was found in store, assign it as current value in combobox if (record) { combo.setValue(record.data.language); } } else { // no language found, default to english this.setup(); } Ext.tip.QuickTipManager.init(); }, onSuccess: function(response) { try { eval(response.responseText); } catch (e) { Ext.Msg.alert('Failure', e.toString()); } this.setup(); }, onFailure: function() { Ext.Msg.alert('Failure', 'Failed to load locale file.'); this.setup(); }, setup: function() { Ext.create('Ext.FormPanel', { renderTo: 'datefield', margin: '10, 0, 0, 10', frame: true, title: 'Date picker', width: 380, defaultType: 'datefield', items: [{ fieldLabel: 'Date', name: 'date' }] }); Ext.create('Ext.FormPanel', { renderTo: 'emailfield', margin: '10, 0, 0, 10', labelWidth: 100, frame: true, title: 'E-mail Field', width: 380, defaults: { msgTarget: 'side', width: 340 }, defaultType: 'textfield', items: [{ fieldlabel: 'Email', name: 'email', vtype: 'email' }] }); var monthArray = Ext.Array.map(Ext.Date.monthNames, function (e) { return [e]; }); var ds = Ext.create('Ext.data.Store', { fields: ['month'], remoteSort: true, pageSize: 6, proxy: { type: 'pagingmemory', data: monthArray, reader: { type: 'array' } } }); Ext.create('Ext.grid.Panel', { renderTo: 'grid', margin: '10, 0, 0, 10', width: 380, height: 203, title:'Month Browser', columns:[{ text: 'Month of the year', dataIndex: 'month', width: 240 }], store: ds, bbar: Ext.create('Ext.toolbar.Paging', { pageSize: 6, store: ds, displayInfo: true }) }); // trigger the data store load ds.load(); } }; })(); MultiLangDemo.init(); });
以上仅是ExtJS UI自身的本地化。
自己系统中的文字如何本地化呢?
余的做法基本是沿着ExtJS本地化的思路,将系统用到的字符串集中在单个文件中,这也有利于后期扩展更多的语言
像Date picker/Email Field/Month Browser/Month of the year就是系统自身的语言,不应该硬编码到UI中
在加载ExtJS语言文件的时候,同时也加载系统自身的语言文件进行刷新
系统语言文件也必须使用和ExtJS语言文件相同的后缀,如en/ja/zh_CN/zh_TW
效果:
演示页面:multiplelanguages.html
逻辑+UI:multiplelanguages.js
语言列表RawData:languages.js(和上面一样)
系统默认语言文件(必须):myproject-js/myproject-lang.js(余将默认语言弄成了日文)
系统的本地化语言文件(可选):(没有参数时会保留默认语言文件中的设定)
locale/myproject-lang-en.js
locale/myproject-lang-ja.js
locale/myproject-lang-zh_CN.js
locale/myproject-lang-zh_TW.js
multiplelanguages.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Localization example</title> <!-- Ext Library Files --> <script src="myproject-js/myproject-lang.js"></script> <link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css"> <script src="ext/ext-all-debug.js"></script> <!-- App Scripts --> <script src="languages.js"></script> <script src="multiplelanguages.js"></script> </head> <body> <div id="languages"></div> <div id="datefield"></div> <div id="emailfield"></div> <div id="grid"></div> </body> </html>
multiplelanguages.js
将UI的生成全部集中到setup函数里了
/** * by kuyur@kuyur.info * 2012.2.3 */ Ext.Loader.setConfig({ enabled: true }); Ext.Loader.setPath('Ext.ux', 'ext/examples/ux/'); Ext.require(['Ext.data.*', 'Ext.tip.QuickTipManager', 'Ext.form.*', 'Ext.ux.data.PagingMemoryProxy', 'Ext.grid.Panel']); Ext.onReady(function() { var params; MultiLangDemo = (function() { return { init: function() { // load ExtJS locale params = Ext.urlDecode(window.location.search.substring(1)); if (params.lang) { var url = Ext.util.Format.format('ext/locale/ext-lang-{0}.js', params.lang); Ext.Ajax.request({ url: url, success: this.onLoadExtLocaleSuccess, failure: this.onLoadExtLocaleFailure, scope: this }); } else { // no language found, locale of ExtJS will be english as default this.loadmyprojectLocale(); } }, onLoadExtLocaleSuccess: function(response) { try { eval(response.responseText); } catch (e) { Ext.Msg.alert('Failure', e.toString()); } this.loadmyprojectLocale(); }, onLoadExtLocaleFailure: function() { Ext.Msg.alert('Failure', 'Failed to load locale file.'); this.loadmyprojectLocale(); }, loadmyprojectLocale: function() { // load locale for myproject if (params.lang) { var urlmyprojectLocale = Ext.util.Format.format('locale/myproject-lang-{0}.js', params.lang); Ext.Ajax.request({ url: urlmyprojectLocale, success: this.onLoadmyprojectLocaleSuccess, failure: this.onLoadmyprojectLocaleFailue, scope: this }); } else { this.setup(); } }, onLoadmyprojectLocaleSuccess: function(response) { try { eval(response.responseText); } catch (e) { Ext.Msg.alert('Failure', e.toString()); } this.setup(); }, onLoadmyprojectLocaleFailue: function() { Ext.Msg.alert('Failure', 'Failed to load myproject locale file.'); this.setup(); }, setup: function() { var store = Ext.create('Ext.data.ArrayStore', { fields: ['code', 'language'], data: Ext.local.languages //from languages.js }); var combo = Ext.create('Ext.form.field.ComboBox', { renderTo: 'languages', margin: '10, 0, 0, 10', store: store, displayField: 'language', queryMode: 'local', emptyText: myproject.Message.SelectALanguage, hideLabel: true, width: 200, listeners: { select: { fn: function(cb, records) { var record = records[0]; window.location.search = Ext.urlEncode({ "lang": record.get("code") }); }, scope: this } } }); if (params.lang) { // check if there's really a language with passed code var record = store.findRecord('code', params.lang, null, null, null, true); // if language was found in store, assign it as current value in combobox if (record) { combo.setValue(record.data.language); } } Ext.create('Ext.FormPanel', { renderTo: 'datefield', margin: '10, 0, 0, 10', frame: true, title: myproject.Message.PickDate, width: 380, defaultType: 'datefield', items: [{ fieldLabel: myproject.Message.Date, name: 'date' }] }); Ext.create('Ext.FormPanel', { renderTo: 'emailfield', margin: '10, 0, 0, 10', labelWidth: 100, frame: true, title: myproject.Message.EmailFieldTitle, width: 380, defaults: { msgTarget: 'side', width: 340 }, defaultType: 'textfield', items: [{ fieldlabel: 'Email', name: 'email', vtype: 'email' }] }); var monthArray = Ext.Array.map(Ext.Date.monthNames, function(e) { return [e]; }); var ds = Ext.create('Ext.data.Store', { fields: ['month'], remoteSort: true, pageSize: 6, proxy: { type: 'pagingmemory', data: monthArray, reader: { type: 'array' } } }); Ext.create('Ext.grid.Panel', { renderTo: 'grid', margin: '10, 0, 0, 10', width: 380, height: 203, title: myproject.Message.MonthList, columns: [{ text: myproject.Message.MonthTitle, dataIndex: 'month', width: 240 }], store: ds, bbar: Ext.create('Ext.toolbar.Paging', { pageSize: 6, store: ds, displayInfo: true }) }); // trigger the data store load ds.load(); } }; })(); MultiLangDemo.init(); });
myproject-js/myproject-lang.js
/** * by kuyur@kuyur.info * 2012.2.3 */ var myproject = {}; myproject.Message = {}; myproject.Message.SelectALanguage = '言語を選択ください...'; myproject.Message.PickDate = '日付を選択'; myproject.Message.Date = '日付'; myproject.Message.EmailFieldTitle = 'メールアドレス'; myproject.Message.MonthList = '月の一覧'; myproject.Message.MonthTitle = '月順';
locale/myproject-lang-en.js
/** * by kuyur@kuyur.info * 2012.2.3 */ if (myproject.Message) { myproject.Message.SelectALanguage = 'Select a language...'; myproject.Message.PickDate = 'Date Picker'; myproject.Message.Date = 'Date'; myproject.Message.EmailFieldTitle = 'Email'; myproject.Message.MonthList = 'Month Browser'; myproject.Message.MonthTitle = 'Month of the year'; }
locale/myproject-lang-ja.js
/** * by kuyur@kuyur.info * 2012.2.3 */ if (myproject.Message) { myproject.Message.SelectALanguage = '言語を選択ください...'; myproject.Message.PickDate = '日付を選択'; myproject.Message.Date = '日付'; myproject.Message.EmailFieldTitle = 'メールアドレス'; myproject.Message.MonthList = '月の一覧'; myproject.Message.MonthTitle = '月順'; }
locale/myproject-lang-zh_CN.js
/** * by kuyur@kuyur.info * 2012.2.3 */ if (myproject.Message) { myproject.Message.SelectALanguage = '请选择一种语言...'; myproject.Message.PickDate = '选择日期'; myproject.Message.Date = '日期'; myproject.Message.EmailFieldTitle = '电子邮件地址'; myproject.Message.MonthList = '月份一览'; myproject.Message.MonthTitle = '月份'; }
locale/myproject-lang-zh_TW.js
/** * by kuyur@kuyur.info * 2012.2.3 */ if (myproject.Message) { myproject.Message.SelectALanguage = '請選擇一種語言...'; myproject.Message.PickDate = '選擇日期'; myproject.Message.Date = '日期'; myproject.Message.EmailFieldTitle = '電子郵件地址'; myproject.Message.MonthList = '月份一覽'; myproject.Message.MonthTitle = '月份'; }
注意事项:
1.ExtJS库的解压目录名要一致,代码中的为ext
2.由于AJAX的本地请求会因为安全问题被浏览器禁止,需要将文件放到服务器才能测试
相关推荐
- 加载资源后,EXTJS会自动替换应用中的所有本地化字符串。 3. **创建本地化组件**: - EXTJS的组件如按钮、菜单、表单等,都可以进行国际化。开发者需要确保在创建组件时,使用的是动态加载的本地化字符串,而...
6. **Ajax和数据管理**:EXTJS4内置了强大的Ajax请求处理和数据管理机制,通过Ext.data.Proxy和Ext.data.Store可以轻松处理远程数据请求和本地数据存储。 7. **可访问性**:EXTJS4注重无障碍性,遵循WCAG 2.0标准,...
样式文件`ext-all.css`用于加载组件的样式,`ext-all.js`引入核心组件和驱动,而`ext-lang-zh_CN.js`实现中文本地化。 最后,使用`Ext.onReady()`函数来初始化ExtJS组件库。当页面加载完成并且DOM准备就绪时,`Ext....
这款图片浏览器利用了ExtJS4的组件化、数据绑定和事件处理等特性,为用户提供了一个交互性强、功能丰富的图片浏览体验。 在实现这个图片浏览器的过程中,开发者可能使用了以下核心ExtJS4组件和技术: 1. **Panel...
ExtJS TreeGrid是一种结合了表格和树形结构的组件,常用于展示层次化的数据,它在ExtJS库中提供了一种高效且灵活的方式来展现多级数据。在这个“Extjs treeGrid 本地数据 例子”中,我们将探讨如何使用ExtJS创建一个...
ExtJS4是一款强大的JavaScript库,专门用于构建富客户端应用程序。TreeGrid是ExtJS中的一个组件,结合了树形视图和表格的优点,可以用来展示层次结构的数据并支持数据的排序、筛选和操作。在本实例中,我们关注的是...
在ExtJS4中,数据管理通常通过Store完成,它可以连接到各种数据源,包括JSONP、Ajax请求或者本地存储。对于与后台的交互,通常使用AJAX技术,通过Ext.Ajax或Ext.data.proxy.Ajax来发送异步请求,获取或提交数据。这...
综上所述,ExtJS 4 Desktop结合MVC模式提供了强大的工具,帮助开发者构建富交互、桌面化的Web应用。通过PHP作为后端,可以实现高效的数据通信,为用户提供无缝的体验。了解并掌握这些知识点对于开发高质量的Web桌面...
在TreeGrid中,这意味着列标题、提示信息和其他用户界面元素都可以轻松地本地化。 2. **TreeGrid的基本结构**:TreeGrid由一个树节点结构和一个数据网格组成。树节点负责显示层级关系,而数据网格则用于显示行数据...
Extjs的`Ext.util.Format`类提供了一组内置的格式化函数,用于文本、日期和数字的格式化。还可以自定义格式化函数,或者通过`XTemplate`进一步自定义内容。 #### 8. 组件结构 Extjs的组件结构复杂且功能强大,包括...
在描述中提到的“汉化包”意味着这个工具已经进行了本地化处理,适应了中文环境,这对于中国开发者来说是一个极大的便利,避免了语言障碍,使得理解和操作更加直观。"使用说明包里有"表明工具附带了详细的使用指南,...
当你解压并覆盖到之前安装的`xds_preview.air`文件所在的目录时,实际上是在更新和本地化开发工具,使其显示中文界面,这对于中文用户来说,无疑提高了理解和操作的便捷性。 在使用ExtJS可视化开发工具时,开发者...
5. **本地化** ExtJS4支持多语言,因此日期控件可以根据用户的浏览器设置或者手动配置显示不同语言的日期和时间格式。 6. **自定义渲染** 通过使用`renderer`函数,你可以自定义日期字段的显示方式,这在需要特殊...
4. **汉化支持**:提供的汉化文件意味着该设计器已经进行了本地化处理,用户界面和文档都转换成了中文,这对于中文开发者来说更加友好,降低了学习和使用的难度。 5. **安装说明**:安装说明.txt文件包含了详细的...
ExtJS4是一个强大的JavaScript库,专门用于构建富客户端应用程序,特别是复杂的Web应用界面。这个"webdesktop1.0"压缩包包含了一个基于ExtJS4实现的Web桌面小实例,旨在帮助开发者了解如何利用ExtJS4构建类似桌面...
根据提供的文件信息,本文将详细解析ExtJS 4中如何处理不同类型的Store及与之相关的数据操作、模型定义以及前端展示等内容。 ### ExtJS 4中的Store与数据管理 #### Store概念简介 在ExtJS 4中,Store是用于存储...
9. **国际化支持**:如果源代码包含了多语言支持,开发者可以学习如何在ExtJS应用中实现语言切换,这通常涉及到资源配置和本地化处理。 10. **最佳实践**:通过阅读源代码,开发者可以学习到如何组织代码结构、编写...
《4.0Ext 本地化:打造符合用户文化的交互体验》 在当今全球化的时代,软件应用不仅要功能强大,还要能够适应不同地区的语言和文化习惯。4.0Ext 提供了强大的本地化功能,帮助开发者为用户提供更加贴心的界面体验。...
7. **国际化(Internationalization)**:7.6 SDK可能进一步完善了多语言支持,让开发者能轻松地为全球用户提供本地化应用。 8. **开发工具升级**:更新的Sencha CMD或WebPack插件可能是SDK的一部分,帮助开发者更...