国际化Ext项目

"橘生淮南则为橘,生于淮北则为枳"。同样一件东西,在不同的地域和语言文化环境下,会有不同的称谓和使用习惯。何谓本地化?简单说来,就是根据当地的语言文化情况和市场特征,对目标信息和产品的再次加工。举个例子,法国生产的化妆品希望进入中国卖给中国消费者,商家必须根据中国妇女的皮肤特性、中国化妆品市场情况等制定产品策略和价格策略,进行市场营销,这个过程就是本地化的过程。

现代应用程序框架设计中常常需要考虑到国际因素,为了满足全球用户的需求,当今的Web应用程序通常都需要国际化。在这里,应用程序的国际化与本地化并非同一个概念。

 
 

为了支持本地化,应用程序在设计上必须进行一些调整。一般说来,这些调整发生在两个阶段,一个是在软件工程的概要设计上,需要预留本地化支持的开发过程、设计、日程和时间表;二是在详细设计/编码过程,需要开发人员遵照某些要求和规范编写需要本地化的应用程序部分。此外,还应增加本地化小组,以及相应的项目日程表;在测试阶段,增加本地化测试环节和日程。最后还需要在部署阶段和相应的阶段中增加本地化版本支持。

我们现在要讲的应属于第二个阶段,在编码过程中如何实现Ext程序的本地化功能,那么在开发过程中,你的Ext代码必须支持国际化,才能方便地实现本地化。一般来说,实现国际化的技术方法大概有以下几种:

浏览器向服务器发送请求,服务器端收到请求后根据浏览器的语言设置从相应的语言资源文件中提出数据,或者转发到相应的Html页面或JSP页面。

首先进入选择语言的页面,选择不同的语言链接,此链接会打开相应的语言界面。

首先进入选择语言的界面,选择不同的语言链接,组装成带有语言编码标识的url,然后浏览器根据此url向服务端发出请求,服务端向浏览器返回请求的HTML页面,浏览器在载入页面以后,根据请求url中的语言编码载入相应的语言文件对页面进行本地化。

Ext是一个充分利用面向对象概念来设计的一个框架,松耦合、高内聚的特点让它本身的组件与使用Ext开发的程序能够轻松地实现系统的国际化功能,所以Ext框架本身也内置了各国语言的本地化文件,位于source\locale包中。local包中的文件只支持对日期显示,控件校验提示的本地化功能,单独使用它并不能做到整个系统的国际化功能,当然Ext不会知道你的系统使用的是什么文本,Ext为我们预留了本地化的接口,我们可以方便地实现对系统的本地化功能。

现在,我们根据第3种方法来演示如何本地化Ext,在下面的示例中,可支持3种语言本地化功能,包括汉语、英语、日语,选择相应语言,界面会有相应的变化,我们先来预览一下3种语言不同的界面,如图10.3、10.4和10.5所示。

 
图10.3  英文的界面

 
(点击查看大图)

 
(点击查看大图)图10.5  日文的界面

下面是实现本地化功能示例的全部源代码。

HTML代码清单10-3-1

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title id="title">本地化例子</title>
<link rel="stylesheet" type="text/css"
href="../../resources/css/ext-all.css">
<script type="text/javascript" src="../../adapter/ext/ext-base.js">
</script>
<script type="text/javascript" src="../../ext-all-debug.js">
</script>
<script type="text/javascript" src="../locale/PagingMemoryProxy.js">
</script>
<!-- Ext localization javascript -->
<script type="text/javascript" id="extlocale">
</script>
<script type="text/javascript">
// decode language passed in url
var locale = window.location.search ?
Ext.urlDecode(window.location.search.substring(1)).locale : '';
var head = Ext.fly(document.getElementsByTagName('head')[0]);
if (locale) {
Ext.fly('extlocale').set({
src: '../../source/locale/ext-lang-' + locale + '.js'
});
}
</script>
<script type="text/javascript" id="applocale">
</script>
<script type="text/javascript" src="importScript.js">
</script>
<!-- Main application -->
<script type="text/javascript">
var grid;
Ext.onReady(function(){
Ext.BLANK_IMAGE_URL = '../../resources/images/default/s.gif';
Ext.QuickTips.init();
Ext.form.Field.prototype.msgTarget = 'side';
/**************************************************************/
var fm = Ext.form, Ed = Ext.grid.GridEditor;
var monthArray = Date.monthNames.map(function(e){
return [e];
});
var ds = new Ext.data.Store({
proxy: new Ext.data.PagingMemoryProxy(monthArray),
reader: new Ext.data.ArrayReader({}, [{
name: 'month'
}])
});
var cm = new Ext.grid.ColumnModel([{
header: "Months of the year",
id: 'monthID',
dataIndex: 'month',
editor: new Ed(new fm.TextField({
allowBlank: false
})),
width: 240
}]);
cm.defaultSortable = true;
grid = new Ext.grid.GridPanel({
//frame:true,
width: 475,
height: 215,
title: 'Month Browser',
store: ds,
cm: cm,
sm: new Ext.grid.RowSelectionModel({
selectRow: Ext.emptyFn
}),
bbar: new Ext.PagingToolbar({
pageSize: 6,
store: ds,
displayInfo: true
})
});
// trigger the data store load
ds.load({
params: {
start: 0,
limit: 6
}
});
/**************************************************************/
// create pre-configured example window extension class
Ext.ns('Tutorial');
Tutorial.LocalizationWin = Ext.extend(Ext.Window, {
titleText: 'Localization Example',
selectLangText: 'Select Language',
textFieldText: 'Text Field',
dateFieldText: 'Date Field',
monthText: 'Month Localizing..',
initComponent: function(){
Ext.apply(this, {
width: 500,
id: 'winid',
height: 350,
layout: 'fit',
border: false,
closable: false,
title: this.titleText,
items: [{
xtype: 'form',
frame: true,
defaultType: 'textfield',
items: [{
xtype: 'combo',
fieldLabel: this.selectLangText,
name: 'locale',
store: new Ext.data.SimpleStore({
id: 0,
fields: ['file', 'locale'],
data: [['', 'English'], ['zh_CN', 'Chinese'],
['ja', 'Japanese']]
}),
listeners: {
select: {
fn: function(combo){
window.location.search = '?' +
Ext.urlEncode({
locale: combo.getValue()
});
}
}
},
mode: 'local',
editable: false,
forceSelection: true,
valueField: 'file',
displayField: 'locale',
triggerAction: 'all',
value: locale
}, {
fieldLabel: this.textFieldText,
allowBlank: false
}, {
xtype: 'datefield',
fieldLabel: this.dateFieldText,
allowBlank: false
}, {
xtype: 'label',
text: this.monthText,
style: 'top:200px'
}, grid]
}]
});
Tutorial.LocalizationWin.superclass.initComponent
.apply (this, arguments);
}
});
function callback(){
appMain();
}
if (locale) {
importScript('app-lang-' + locale + '.js', callback);
}
else {
appMain();
}
function appMain(){
var win = new Tutorial.LocalizationWin();
win.show();
}
});
</script>
</head>
<body>
</body>
</html>
JavaScript代码清单10-3-2 (app-lang-zh_CN.js)
/**
* 简体中文的本地化文件
*/
if(Tutorial.LocalizationWin) {
Ext.override(Tutorial.LocalizationWin, {
titleText:'本地化 示例'
,selectLangText:'选择语言'
,textFieldText:'文本 字段'
,dateFieldText:'日期 字段'
,monthText:'本地化月份..'
});
}
grid.setTitle('月份浏览');
grid.getColumnModel().getColumnById('monthID').header='一年的月份';
JavaScript代码清单10-3-3 (app-lang-ja.js)
/**
* 日文的本地化文件
*/
if(Tutorial.LocalizationWin) {
Ext.override(Tutorial.LocalizationWin, {
titleText:'ローカル化サンプル'
,selectLangText:'言語'
,textFieldText:'テキスト'
,dateFieldText:'日付'
,monthText:'ローカル化月..'
});
}
grid.setTitle('月プレビュー');
grid.getColumnModel().getColumnById('monthID').header='月';
JavaScript代码清单10-3-4 (importScript.js)
/*
导入相应的语言资源文件,并执行回调函数
*/
function importScript(src, callback){
var script = document.createElement("script");
if (script.addEventListener)
script.addEventListener("load", callback, false);
else
if (script.attachEvent)
script.attachEvent("onreadystatechange", function(){
importScript.callbackForIE(callback);
});
script.src = src;
document.getElementsByTagName("head")[0].appendChild(script);
}
importScript.callbackForIE = function(callback){
var target = window.event.srcElement;
if (target.readyState == "loaded" || target.readyState == "complete")
callback.call(target);
};

在上面的Ext本地化示例中的过程如下。

(1) 浏览器向服务端请求页面文件。

(2) 服务端返回后页面文件在浏览器中解析时,首先会判断请求的url中是否包含local字符串,即本地编码:

如果不包含,那么会使用Ext默认的英文本地化文件进行载入。

如果包含,比如local=zh_CN或者local=ja,那么会根据此编码值拼接成Ext本地化包中相应的本地化文件名称,并且通过Ext.fly方法设置ID为extlocal的script标签的src的值为Ext内置的本地化文件,此时浏览器会载入此文件。

(3) 接着创建了一个Grid组件,此组件从浏览器载入的Ext内置本地化文件中的Date.monthNames数组中读取数据,可见上文中见到的local编码值的重要性,载入不同的本地化文件,Date.monthNames的值将会不同,那么Grid组件的内容也会发生变化。

(4) 然后继续创建了一个窗口组件,窗口中包含选择语言编码的列表,文本字段输入域,日期字段输入域,并包含了上面创建的Grid组件。

读者应该可以看到代码中,Tutorial.LocalizationWin继承了Ext.Window组件类,并新增了自己的配置属性,即文本字段、日期字段、窗体Title等的显示文本。在初始化这些组件的时候,引用了外部的显示文本如textFieldText,这样,就创建出了一套优雅的国际化代码,为后面的本地化实现打下了基础。

接下来的是以下这段代码:

if(locale) {
importScript('app-lang-' + locale + '.js', callback);
}

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值