热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SAPUI5(21)-如何实现多语言

在SAPUI5中,通过两种方法来实现多语言,一是SAPUI5提供ResourceModel,ResourceModel读取资源包(ResourceBundle)并与Vie

在 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)。

1) URL中的 locale 参数(即在 url 后面加上 ?sap-ui-language=xx )
2) 应用程序代码的 locale 设置,比如:

sap.ui.getCore().getConfiguration().applySettings({ language: 'de', calendarType: sap.ui.core.CalendarType.Gregorian, formatSettings: { legacyDateFormat: '1', legacyTimeFormat: '1', legacyNumberFormat: '1' }
});

3) Android 平台的用户代理字符串设置
4) 浏览器的一般语言设置,可以用 window.navigator.language 查看
5) 浏览器中用户语言配置。这个与浏览器相关,比如 IE 通过 window.navigator.userLanguage 查看。
6) 浏览器语言配置。这个业余浏览器相关,比如 IE 通过 window.navigator.browserLanguage 查看
7) OpenUI5中硬编码,默认为 en

资源包文件

资源包文件就是 Java 的属性文件( Properties 文件)。文件中包含与语言相关的文本。资源包文件的特征:

  1. 文件的扩展名总是 .properties
  2. 文件名包括固定部分和语言相关部分。比如在 OpenUI5 中,大家习惯将 Resource Bundle 的文件名叫做 i18n(来源于 internationalization 这个单词,取首位两个字母,中间字母数为18)。那么 i18n.properties 是默认的文件(如果没有其他文件,就用这个文件作为默认设置),i18n_zh_CN.properties 是中文简体的资源文件,依此类推。
  3. 资源包文件为扁平结构,不能嵌套。每一行要么是 key-value pair ,要么是 # 开头的注释。也可以可以空行。key-value pair 没有引号。后面有资源包文件的例子。
  4. 如果 Properties 文件的文本为 Unicode 字符,文件使用16进制的编码来存储,而不是明文。这样对开发人员来说,友好性较差。

Resource Model 及数据绑定

我们继续对前面显示供应商 Master-detail 的程序进行重构,增加程序多语言的功能。Eclipse 的项目文件结构如下:

使用 Resource Model 绑定数据需要三步:
1) 添加资源包文件,将不同的语言放在不同的资源包文件中。本示例给出两个资源包文件:

  • 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

2) 在 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 这个消息给用户。

1) 先在 i18n.properties 文件中添加 key-value:

msgCurrLanguage=Current Language is {0}

在 i18n_zh_CN.properties 中添加 msgCurrLanguage 的中文显示:

msgCurrLanguage=\u5F53\u524D\u8BED\u8A00\u662F {0}

2) 在 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>            
        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 浏览器),当在中文环境中,显示:

中文

当在英文环境中,显示:

英文

源代码

21_zui5_resource_model

参考
  • Identifying the Language Code / Locale


推荐阅读
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 本文总结了Java中日期格式化的常用方法,并给出了示例代码。通过使用SimpleDateFormat类和jstl fmt标签库,可以实现日期的格式化和显示。在页面中添加相应的标签库引用后,可以使用不同的日期格式化样式来显示当前年份和月份。该文提供了详细的代码示例和说明。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Ihavethefollowingonhtml我在html上有以下内容<html><head><scriptsrc..3003_Tes ... [详细]
author-avatar
Timma2116
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有