1. 背景
i18n 是 “internationalization” 的缩写,其中的 18 是 “internationalization” 这个单词中间的字符数。i18n 是一种让应用程序支持多种语言的方法,也就是我们通常所说的国际化。
在SAPUI5中,i18n主要通过使用资源模型(Resource Model)和资源束(Resource Bundle)来实现。资源模型是一种特殊的模型,它可以用来管理和访问资源束。资源束是一组键值对,其中的键是标识符,值是对应的本地化字符串。
2. 示例
下面是一个简单的例子:
首先,创建一个i18n资源束文件(例如:i18n.properties
),并在其中定义你的本地化字符串:
helloMessage=Hello, World!
然后,你需要在你的应用程序中创建一个资源模型,并将它绑定到你的视图或控制器:
sap.ui.define(["sap/ui/core/mvc/Controller","sap/ui/model/resource/ResourceModel"
], function(Controller, ResourceModel) {"use strict";return Controller.extend("my.app.controller", {onInit: function() {var i18nModel = new ResourceModel({bundleName: "my.app.i18n.i18n"});this.getView().setModel(i18nModel, "i18n");}});
});
最后,你可以在你的视图中使用这些本地化字符串:
<Text text="{i18n>helloMessage}" />
在这个例子中,{i18n>helloMessage}
是一个绑定表达式,它告诉SAPUI5从名为 “i18n” 的模型中获取键为 “helloMessage” 的值。这个值就是我们在i18n.properties
文件中定义的本地化字符串。
3. 练习
在上一篇博客练习的基础上,让我们将UI的文本移动到一个单独i18n
资源文件中。
这样,所有的文本字符都集中在一个位置,可以很容易地翻译成其他语言。
3.1 创建i18n文件
我们在 webapp/i18n
文件夹下创建 i18n.properties
文件。文本的属性文件包含每个元素的名称-值
对。可以通过添加大括号
向文本添加任意数量的参数。大括号中的数字对应访问参数的顺序(从 0 开始)。
在本练习中,我们只会有一个 i18n.properties
属性文件。
在实际项目中,将会为每种支持的语言单独创建一个文件,附加区域后缀,比如 i18n_de.properties
为德语,i18n_en.properties
为英语,依此类推。当用户运行应用程序时,SAPUI5 会加载适合用户环境的语言文件。
创建好的 i18n.properties
文件内容如下:
showHelloButtonText=Say Hello
helloMsg=Hello {0}
3.2 增强App.controller.js文件
在 onInit
函数中,我们实例化资源模型 ResourceModel
。
资源束bundleName为 zsapui5.test.i18n.i18n
, 由应用程序命名空间 zsapui5.test
(在 index.html
中定义)、文件夹名称 i18n
和最后一个没有扩展名的文件名 i18n
组成。SAPUI5 运行时会计算资源的正确路径,也即找到i18n.properties
文件。
...
const i18nModel = new ResourceModel({bundleName: "zsapui5.test.i18n.i18n");...
接下来,将资源模型的实例绑定到视图上(模型实例设置为带有键i18n的命名模型)。
...
this.getView().setModel(i18nModel, "i18n");
...
在 onShowHello
事件处理程序函数中,我们访问 i18n 模型,从消息包文件中获取文本,并用数据模型中的/recipient/name
替换占位符 {0}
。
...onShowHello: function () {// read msg from i18n modelconst oBundle = this.getView().getModel("i18n").getResourceBundle();const sRecipient = this.getView().getModel().getProperty("/recipient/name");const sMsg = oBundle.getText("helloMsg", [sRecipient]);// show messageMessageToast.show(sMsg);}
...
getProperty()
方法可以在任何模型中调用,并将数据路径作为参数。
此外,资源包ResouceBundle具有一个特定的 getText()
方法,该方法将字符串数组作为第二个参数,来替换文本中的非静态数据,而不是手动连接可翻译文本。
在运行时,SAPUI5 会根据您的浏览器设置和区域设置尝试加载正确的 i18n_.properties
文件。
在此例中,我们只创建了一个i18n.properties
文件以简化操作。
但是,可以在浏览器的开发者工具的网络流量中看到 SAPUI5 在回退到默认的 i18n.properties 文件之前,尝试加载一个或多个 i18n_.properties 文件。
改动后的App.controller.js文件最终代码如下:
sap.ui.define(["sap/ui/core/mvc/Controller","sap/m/MessageToast","sap/ui/model/json/JSONModel","sap/ui/model/resource/ResourceModel"
], function (Controller, MessageToast, JSONModel, ResourceModel) {"use strict";return Controller.extend("zsapui5.test.controller.App", {onInit: function () {//set data model on viewconst oData = {recipient: {name: "World"}};const oModel = new JSONModel(oData);this.getView().setModel(oModel);// set i18n model on viewconst i18nModel = new ResourceModel({bundleName: "zsapui5.test.i18n.i18n"});this.getView().setModel(i18nModel, "i18n");},onShowHello: function () {// read msg from i18n modelconst oBundle = this.getView().getModel("i18n").getResourceBundle();const sRecipient = this.getView().getModel().getProperty("/recipient/name");const sMsg = oBundle.getText("helloMsg", [sRecipient]);// show messageMessageToast.show(sMsg);}});
});
3.3 增强App.view.xml文件
在XML视图中,将按钮文本连接到i18n模型中的showHelloButtonText
属性。
...<Button text="{i18n>showHelloButtonText}"press = ".onShowHello"/>
...
资源包是一个扁平结构,因此路径前面的斜杠
(/)
可以省略。
改动后的App.view.xml文件如下:
<mvc:ViewcontrollerName="ui5.walkthrough.controller.App"xmlns="sap.m"xmlns:mvc="sap.ui.core.mvc"><Buttontext="{i18n>showHelloButtonText}"press=".onShowHello"/><Inputvalue="{/recipient/name}"description="Hello {/recipient/name}"valueLiveUpdate="true"width="60%"/>
</mvc:View>
注意: 为了简化展示,此示例中的描述文本并没有完全本地化(例如Input的description中Hello还是hardcoded)。为了安全起见,我们必须使用类似于控制器中的机制来使用资源包中的字符串并替换其中的部分。这可以通过
sap/base/strings/formatMessage
这个格式化程序来完成。
此外,i18n文件仅影响客户端应用程序文本。从后端系统加载的文本,仍然以后端系统支持的所有语言显示。
3.4 编程规范
-
国际化的资源模型被称为i18n模型。
-
默认文件名为
i18n.properties
。 -
资源包键以小写
驼峰
写法编写。 -
资源包的值可以包含参数像
{0}
,{1}
,{2}
,… -
不要拼接(concatenate)需要翻译的字符串
-
对于特殊字符,请使用Unicode转义序列。
3.5 运行程序
运行改动后的程序,效果如下:
显示效果与上篇博客中的效果相同,但如果通过F12来调试下程序,可以在程序加载过程中看到,SAPUI5 在回退到默认的 i18n.properties 文件之前,尝试加载一个或多个 i18n_.properties 文件。
在控制台里,也可以发现这两个错误消息:
4. 小结
本文介绍了SAPUI5框架下,文本国际化的实现方式,并给出了相应的示例代码。