在 SAPUI5 中,通过两种方法来实现多语言,一是 SAPUI5 提供 Resource Model,Resource Model 读取资源包 (Resource Bundle) 并与 View 中的控件绑定。第二种方法是使用 jQuery.sap.resources 相关的 API 读取资源包。两种方法都需要资源包文件并且在配置中设置。
先介绍两个知识点:语言代码和资源包文件。
语言代码
OpenUI5 对语言使用字符串标识,遵循 BCP-47 标准。比如 en 表示英语,en-US 表示美国英语。zh-Hans 表示中文简体,zh-Hant 表示中文繁体。
SAP ABAP 使用的是另外一套专门的编码,比如 ZH 表示中文简体,ZF 表示中文繁体。OpenUI5 能识别 ABAP 的编码并转换成 BCP-47 编码。
OpenUI5 对页面的显示,有一个 当前语言( Current Language ) 的概念,按照当前语言,读取相应的资源包文件,按当前语言显示。那么,当前语言如何确定呢?OpenUI5 按照如下顺序顺序(从高到低),如果都没有找到,最后读取通用设置(比如 i18n.properties)。
- URL中的 locale 参数(即在 url 后面加上 ?sap-ui-language=xx)
- 应用程序代码的 locale 设置,比如:
sap.ui.getCore().getConfiguration().applySettings({
    language: 'de',
    calendarType: sap.ui.core.CalendarType.Gregorian,
    formatSettings: {
        legacyDateFormat: '1',
        legacyTimeFormat: '1',
        legacyNumberFormat: '1'
    }
});
- Android 平台的用户代理字符串设置
- 浏览器的一般语言设置,可以用 window.navigator.language查看
- 浏览器中用户语言配置。这个与浏览器相关,比如 IE 通过 window.navigator.userLanguage查看。
- 浏览器语言配置。这个业余浏览器相关,比如 IE 通过 window.navigator.browserLanguage查看
- OpenUI5中硬编码,默认为 en
资源包文件
资源包文件就是 Java 的属性文件( Properties 文件)。文件中包含与语言相关的文本。资源包文件的特征:
- 文件的扩展名总是 .properties
- 文件名包括固定部分和语言相关部分。比如在 OpenUI5 中,大家习惯将 Resource Bundle 的文件名叫做 i18n(来源于 internationalization 这个单词,取首位两个字母,中间字母数为18)。那么 i18n.properties 是默认的文件(如果没有其他文件,就用这个文件作为默认设置),i18n_zh_CN.properties 是中文简体的资源文件,依此类推。
- 资源包文件为扁平结构,不能嵌套。每一行要么是 key-value pair ,要么是 #开头的注释。也可以可以空行。key-value pair 没有引号。后面有资源包文件的例子。
- 如果 Properties 文件的文本为 Unicode 字符,文件使用16进制的编码来存储,而不是明文。这样对开发人员来说,友好性较差。
Resource Model 及数据绑定
我们继续对前面显示供应商 Master-detail 的程序进行重构,增加程序多语言的功能。Eclipse 的项目文件结构如下:

使用 Resource Model 绑定数据需要三步:
- 添加资源包文件,将不同的语言放在不同的资源包文件中。本示例给出两个资源包文件:
- i18n.properties(默认)
- i18n_zh_CN.properties。(中文简体)
i18n.properties 文件的内容:
#-------------------------------------
# In master page
#-------------------------------------
# master page title
masterTitle=Supplier Overview
# Count of supplier
supplierCount=Supplier count
id=ID
name=Supplier Name
#-------------------------------------
# In detail page
#-------------------------------------
# detail page title
detailTitle=Supplier detail
i18n_zh_CN.properties:
#-------------------------------------
# In master page
#-------------------------------------
# master page title: Supplier Overview
masterTitle=\u4F9B\u5E94\u5546\u6982\u89C8
# Count of supplier
supplierCount=\u4F9B\u5E94\u5546\u6570\u91CF
id=ID
name=\u4F9B\u5E94\u5546\u540D\u79F0
#-------------------------------------
# In detail page
#-------------------------------------
# detail page title: Supplier Detail
detailTitle=\u4F9B\u5E94\u5546\u660E\u7EC6
- 在 Component.js 文件中,创建 Resource model 的实例 。Component.js 的完整代码如下:
sap.ui.define([
        "sap/ui/core/UIComponent",
        "sap/ui/model/json/JSONModel",
        "sap/ui/model/resource/ResourceModel"
    ], 
		
	function(UIComponent, JSONModel, ResourceModel){
		return UIComponent.extend("webapp.Component", {	
			// meta-data
			metadata: {
				"rootView": "webapp.view.App",
				"config": {
					"serviceUrl": "service/data.json",
					"i18nBundle": "webapp.i18n.i18n"
				}
			},
			
			// initialization
			init: function(){				
				UIComponent.prototype.init.apply(this, arguments);
				
				var mConfig = this.getMetadata().getConfig();
				
				// resource bundle
				var oResourceModel = new ResourceModel({
					bundleName: mConfig.i18nBundle
				});
				this.setModel(oResourceModel, "i18n");				
				// application data
				var oModel = new JSONModel(mConfig.serviceUrl);
				this.setModel(oModel);
			},
			
			createContent: function() {					
				// root view
				var oRootView = UIComponent.prototype.createContent.apply(this, arguments);
				oApp = oRootView.byId("app");
				
				return oRootView;				
			}
		});
    }
);
和前一篇的代码相比,代码有如下变更:
- 添加对 sap.ui.model.resource.ResourceModel的依赖:
sap.ui.define([
        "sap/ui/core/UIComponent",
        "sap/ui/model/json/JSONModel",
        "sap/ui/model/resource/ResourceModel"
    ], ...
- 在 metadata 配置中,指定 i18n 文件的位置为 app root->webapp->i18n。最后一个 i18n 表示文件名。文件的扩展名总是 .properties。
metadata: {
    "rootView": "webapp.view.App",
    "config": {
        "serviceUrl": "service/data.json",
        "i18nBundle": "webapp.i18n.i18n"
    }        
- 实例化 Resource Model
// initialization
init: function(){				
    UIComponent.prototype.init.apply(this, arguments);
    
    var mConfig = this.getMetadata().getConfig();
    
    // resource bundle
    var oResourceModel = new ResourceModel({
        bundleName: mConfig.i18nBundle
    });
    this.setModel(oResourceModel, "i18n");				
    // application data
    var oModel = new JSONModel(mConfig.serviceUrl);
    this.setModel(oModel);
},
读取配置 config->i18nBundle ,然后使用 setModel() 方法,设置 Component 的 Model 为 ResourceModel ,并且将其命名为i18n。
3)在 View 中参照 Resource Model 中定义的 key。以 Master View 为例:
<core:View xmlns:core="sap.ui.core" 
           xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
		controllerName="webapp.controller.Master" 
		xmlns:html="http://www.w3.org/1999/xhtml">
		
	<Page title="{i18n>masterTitle}">
		<content>
			<Table items="{/Suppliers}">
			
				<headerToolbar>
					<Toolbar>
						<Label text="{i18n>supplierCount}: {/CountOfSuppliers}" />
					</Toolbar>
				</headerToolbar>
				
				<columns>
					<Column>
						<header><Text text="{i18n>id}" /> </header>
					</Column>
					<Column>
						<header><Text text="{i18n>name}" /> </header>
					</Column>
				</columns>
				
				<items>
					<ColumnListItem type="Navigation" press="onListPress">
						<cells>
							<ObjectIdentifier text="{ID}" />
							<ObjectIdentifier text="{Name}" />
						</cells>
					</ColumnListItem>
				</items>
				
			</Table>
		</content>
		
		<footer>
			<Toolbar>
				<Button text="language information" press="onBtnPress"/>
			</Toolbar>
		</footer>
	</Page>
	
</core:View>
Master页面标题,之前是硬编码,现在变为:Page title="{i18n>masterTitle}"。其它的控件,属性设置相同。
detail view(Detail.view.xml):
<core:View xmlns:core="sap.ui.core" 
           xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
		controllerName="webapp.controller.Detail" 
		xmlns:html="http://www.w3.org/1999/xhtml">
		
	<Page title="{i18n>detailTitle}" showNavButton="true" navButtonPress="onNavPress">
		<content>
			<ObjectHeader title="{Name}" number="ID: {ID}">
				<ObjectAttribute text="{Address/Street}, {Address/City}"/>
			</ObjectHeader>
		</content>
	</Page>
	
</core:View>
启动程序,界面和上篇相同。但我们可在 url 后面添加?sap-ui-language=XXX,实现语言的切换。比如:?sap-ui-language=en切换为英语:


使用 jQuery.sap.resources
如果要在代码中直接使用资源包的文本,OpenUI5 提供了 jQuery.sap.resources 方法。比如我们需要在页面中根据不同的语言,显示不同的提示消息。接下来我们在 Master View 中添加一个按钮( sap.m.Button ),当点击的时候读取资源包文件的 msgCurrLanguage ,然后 alert 这个消息给用户。
- 先在 i18n.properties 文件中添加 key-value:
msgCurrLanguage=Current Language is {0}
在 i18n_zh_CN.properties 中添加 msgCurrLanguage 的中文显示:
msgCurrLanguage=\u5F53\u524D\u8BED\u8A00\u662F {0}
- 在 Master view 的 Page中添加Button:
<footer>
	<Toolbar>
		<Button text="{i18n>languageTitle}" press="onLanButtonPress" />
	</Toolbar>
</footer>
Master View 的完整代码:
<core:View xmlns:core="sap.ui.core" 
           xmlns:mvc="sap.ui.core.mvc" 
           xmlns="sap.m"
		controllerName="webapp.controller.Master" 
		xmlns:html="http://www.w3.org/1999/xhtml">
	<Page id="master" title="{i18n>masterTitle}">
		<content>
			<Table class="sapUiResponsiveMargin" width="auto" items="{/Suppliers}">
				
       <!--  Table的细节省略,请参考之前代码--> 
				
			</Table>			
		</content>
		
		<footer>
			<Toolbar>
				<Button text="{i18n>languageTitle}" press="onLanButtonPress" />
			</Toolbar>
		</footer>
	</Page>
</core:View>
3)在 Master controller 中添加 event handler: onLanButtonPress:
onLanButtonPress: function(oEvent){
	// 添加依赖包
	jQuery.sap.require("jquery.sap.resources");
	
	var sLocale = sap.ui.getCore().getConfiguration().getLanguage();
	var oBundle = jQuery.sap.resources({
		url: "i18n/i18n.properties",
		locale: sLocale
	})
	
	var sMessage = oBundle.getText("msgCurrLanguage", [sLocale]);
	alert(oBundle.getText("msgCurrLanguage", [sLocale]));
}
代码说明:
-  sap.ui.getCore().getConfiguration().getLanguage()获得当前语言。
-  jQuery.sap.resources(...)根据指定的 URL 和 Locale,创建一个新的资源包实例(Creates and returns a new instance of jQuery.sap.util.ResourceBundle using the given URL and locale to determine what to load.)。
-  getText()根据资源包文件的 key,获取与语言相关的 value。
界面效果(Edge 浏览器),当在中文环境中,显示:

当在英文环境中,显示:

 
                   
                   
                   
                   
                             本文介绍SAPUI5中实现多语言的方法,包括使用ResourceModel和jQuery.sap.resources API。详细解释了语言代码和资源包文件的概念,并通过示例展示了如何在实际项目中应用这些技术。
本文介绍SAPUI5中实现多语言的方法,包括使用ResourceModel和jQuery.sap.resources API。详细解释了语言代码和资源包文件的概念,并通过示例展示了如何在实际项目中应用这些技术。
           
       
           
                 
                 
                 
                 
                 
                
               
                 
                 
                 
                 
                
               
                 
                 扫一扫
扫一扫
                     
              
             
                   3263
					3263
					
 被折叠的  条评论
		 为什么被折叠?
被折叠的  条评论
		 为什么被折叠?
		 
		  到【灌水乐园】发言
到【灌水乐园】发言                                
		 
		 
    
   
    
   
             
            


 
            