From dd75e87ffa3f73baf1fe87202e507fc18a7790cb Mon Sep 17 00:00:00 2001 From: Zhicheng WANG Date: Sun, 28 Jun 2020 18:01:47 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=87=8D=E6=96=B0=E7=BF=BB=E8=AF=91?= =?UTF-8?q?=E4=B8=A4=E4=B8=AA=E6=94=B9=E5=8A=A8=E5=BE=88=E5=A4=A7=E7=9A=84?= =?UTF-8?q?=E7=AB=A0=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aio/content/guide/i18n.md | 547 ++++++++++++++++++++++++++++++++++++- aio/content/guide/pipes.md | 230 ++++++++++++++++ 2 files changed, 772 insertions(+), 5 deletions(-) diff --git a/aio/content/guide/i18n.md b/aio/content/guide/i18n.md index e5b305e31d..fd3ddc4a87 100644 --- a/aio/content/guide/i18n.md +++ b/aio/content/guide/i18n.md @@ -1,165 +1,327 @@ # Localizing your app +# 应用本地化 + {@searchKeywords i18n} {@a angular-i18n} *Internationalization* (i18n) is the process of designing and preparing your app to be usable in different locales around the world. *Localization* is the process of building versions of your app for different locales, including extracting text for translation into different languages, and formatting data for particular locales. +*国际化*(i18n)是一个过程,用于对你的应用进行设计和准备以便在全球不同地区使用。*本地化*是指为不同的本地环境构建应用版本的过程,包括提取用于翻译成不同语言的文本,以及格式化特定本地环境的数据。 + A *locale* identifies a region (such as a country) in which people speak a particular language or language variant. The locale determines the formatting and parsing of dates, times, numbers, and currencies as well as measurement units and the translated names for time zones, languages, and countries. +*本地环境(locale)*用于标识某个区域(例如某个国家/地区),人们会在该区域内使用特定的语言或语言变体。本地环境决定了日期、时间、数字和货币的格式和解析方式,以及各种测量单位和时区、语言、国家/地区的翻译名称。 +
Create an adaptable user interface for all of your target locales that takes into consideration the differences in spacing for different languages. For details, see [How to approach internationalization](https://marketfinder.thinkwithgoogle.com/intl/en_us/guide/how-to-approach-i18n/#overview "How to approach internationalization"). +要为所有目标本地环境创建一个与之相适应的用户界面,并考虑到不同语言中的间距差异。欲知详情,请参阅[如何实现国际化](https://marketfinder.thinkwithgoogle.com/intl/en_us/guide/how-to-approach-i18n/#overview "如何实现国际化") 。 +
Use Angular to internationalize your app: +使用 Angular 来国际化你的应用: + * Use built-in pipes to display dates, numbers, percentages, and currencies in a local format. + + 使用内置管道来以本地格式显示日期、数字、百分比和货币。 + * Mark text in component templates for translation. + + 标记出组件模板中要翻译的文字。 + * Mark plural forms of expressions for translation. + + 标记出要翻译的表达式的复数形式。 + * Mark alternate text for translation. + 标记出要翻译的备用文字。 + After preparing your app for an international audience, use the [Angular CLI](cli) to localize your app by performing the following tasks: +在为国际用户准备好应用之后,通过执行以下任务,来用 [Angular CLI](cli) 本地化你的应用: + * Use the CLI to extract marked text to a _source language_ file. + + 用 CLI 命令把标记过的文本提取到*源语言*文件中。 + * Make a copy of this file for each language, and send these _translation files_ to a translator or service. + + 把这个文件为每种语言复制一份,并把这些*翻译文件*发给翻译人员或翻译服务。 + * Use the CLI to merge the finished translation files when building your app for one or more locales. + 在为一个或多个本地环境构建应用时,使用 CLI 来合并这些翻译完成的文件。 +
To explore the sample app with French translations used in this guide, see the . + 要探索本指南中使用的法语翻译示例应用,请参阅。 +
## Prerequisites +## 先决条件 + To prepare your app for translations, you should have a basic understanding of the following: +要准备翻译你的应用,你应该对这些内容有一个基本的了解: + * [Templates](guide/glossary#template "Definition of a template") + + [模板](guide/glossary#template "模板的定义") + * [Components](guide/glossary#component "Definition of a component") + + [组件](guide/glossary#component "组件的定义") + * [Angular CLI](guide/glossary#command-line-interface-cli "Definition of CLI") command-line tool for managing the Angular development cycle + + 用来管理 Angular 开发周期的 [Angular CLI](guide/glossary#command-line-interface-cli "CLI 的定义") 命令行工具 + * [Extensible Markup Language (XML)](https://www.w3.org/XML/ "W3C: Extensible Markup Language (XML)") used for translation files + 翻译文件中要用到的[可扩展标记语言(XML)](https://www.w3.org/XML/ "W3C:可扩展标记语言(XML)") + ## Steps to localize your app +## 应用本地化的步骤 + To localize your app, follow these general steps: +要本地化你的应用,请执行以下常规步骤: + 1. [Add the localize package](#setting-up-cli). + + [添加 localize 包](#setting-up-cli) 。 + 2. [Refer to locales by ID](#setting-up-locale). + + [按 ID 引用本地环境](#setting-up-locale) 。 + 3. [Format data based on locale](#i18n-pipes). + + [根据本地环境格式化数据](#i18n-pipes) 。 + 4. [Prepare templates for translations](#Template-translations). + + [准备翻译模板](#Template-translations) 。 + 5. [Work with translation files](#ng-xi18n). + + [使用翻译文件](#ng-xi18n) 。 + 6. [Merge translations into the app](#merge). + + [把翻译合并到应用中](#merge) 。 + 7. [Deploy multiple locales](#deploy-locales). + [部署多个本地环境](#deploy-locales) 。 + While following these steps, you can [explore the translated example app](#app-pre-translation). +按照这些步骤进行操作时,可以[浏览已翻译的示例应用](#app-pre-translation) 。 + The following are optional practices that may be required in special cases: +以下是特殊情况下可能用到的一些可选实践: + * [Set the source locale manually](#set-source-manually) if you need to set the [LOCALE_ID](https://angular.io/api/core/LOCALE_ID "API reference for LOCALE_ID") token. + + 如果你需要设置 [LOCALE_ID](https://angular.io/api/core/LOCALE_ID "LOCALE_ID 的 API 参考") 令牌,请[手动设置源本地环境](#set-source-manually) 。 + * [Import global variants of the locale data](#import-locale) for extra locale data. + + [为其他本地化数据导入本地化数据的全局变体](#import-locale) 。 + * [Manage marked text with custom IDs](#custom-id) if you require more control over matching translations. + 如果你要对翻译的匹配方式有更多的控制权,可以[使用自定义 ID 来管理](#custom-id)。 + {@a setting-up-cli} {@a add-localize} ## Add the localize package +## 添加 localize 包 + To take advantage of Angular's localization features, use the Angular CLI to add the `@angular/localize` package to your project: +要利用 Angular 的本地化特性,可以用 Angular CLI 把 `@angular/localize` 包添加到你的项目中: + ng add @angular/localize This command updates your project's `package.json` and `polyfills.ts` files to import the `@angular/localize` package. +这个命令会更新你的项目的 `package.json` 和 `polyfills.ts` 文件,以导入 `@angular/localize` 包。 +
For more information about `package.json` and polyfill packages, see [Workspace npm dependencies](https://angular.io/guide/npm-packages). +有关 `package.json` 和 polyfill 包的更多信息,请参阅[工作空间的 npm 依赖项](https://angular.io/guide/npm-packages) 。 +
If `@angular/localize` is not installed, the Angular CLI may generate an error when you try to build a localized version of your app. +如果没有安装 `@angular/localize`,那么当你试图构建本地化版本的应用时,Angular CLI 就可能会产生错误。 + {@a setting-up-locale} {@a setting-up-the-locale-of-your-app} ## Refer to locales by ID +## 按 ID 引用本地环境 + Refer to a locale using the Unicode *locale identifier* (ID), which specifies the language, country, and an optional code for further variants or subdivisions. +使用 Unicode *本地环境标识符*(ID)来引用本地环境,该*标识符*用于指定语言、国家/地区以及其他变体或细分的可选代码。 +
+
Unicode locale identifiers
+
Unicode 本地环境标识符
+ * For a list of language codes, see [ISO 639-2](https://www.loc.gov/standards/iso639-2/ "ISO 639-2 Registration Authority"). + + 要获取语言代码列表,请参见 [ISO 639-2](https://www.loc.gov/standards/iso639-2/ "ISO 639-2 注册机构") 。 + * IDs conform to the Unicode Common Locale Data Repository (CLDR). For more information about Unicode locale identifiers, see the [CLDR core specification](http://cldr.unicode.org/core-spec#Unicode_Language_and_Locale_Identifiers "CLDR - Unicode Common Locale Data Repository"). + + ID 要符合 Unicode 通用本地化数据仓库(Common Locale Data Repository CLDR)。有关 Unicode 本地环境标识符的更多信息,请参见 [CLDR 核心规范](http://cldr.unicode.org/core-spec#Unicode_Language_and_Locale_Identifiers "CLDR - Unicode 公共本地化数据存储库") 。 + * CLDR and Angular base their identifiers on [BCP47 tags](http://www.rfc-editor.org/rfc/bcp/bcp47.txt "BCP47 Tags for Identifying Languages"). + CLDR 和 Angular 的标识符都基于 [BCP47](http://www.rfc-editor.org/rfc/bcp/bcp47.txt "用于识别语言的 BCP47 标签") 。 +
The ID consists of a language identifier, such as `en` for English or `fr` for French, followed by a dash (`-`) and a locale extension, such as `US` for the United States or `CA` for Canada. For example, `en-US` refers to English in the United States, and `fr-CA` refers to French in Canada. Angular uses this ID to find the correct corresponding locale data. +该 ID 由一个语言标识符组成,例如 `en` 表示英文, `fr` 表示法语,后跟短划线(`-`)和本地环境扩展,比如 `US` 代表美国,`CA` 代表加拿大。比如,`en-US` 是指美国英语区,`fr-CA` 是指加拿大法语区。Angular 使用这种 ID 来查找对应的本地化数据。 +
Many countries, such as France and Canada, use the same language (French, identified as `fr`) but differ in grammar, punctuation, and formats for currency, decimal numbers, and dates. Use a more specific locale ID, such as French for Canada (`fr-CA`), when localizing your app. +许多国家/地区(比如法国和加拿大)都使用相同的语言(法语,标识为 `fr`),但在语法、标点符号、货币格式、十进制数字格式和日期格式方面都有所不同。在本地化你的应用时,可以使用更具体的本地环境 ID,例如加拿大法语区( `fr-CA` )。 +
Angular by default uses `en-US` (English in the United States) as your app's source locale. +Angular 默认使用 `en-US`(美国英语)作为应用的源本地环境。 + The [Angular repository](https://github.com/angular/angular/tree/master/packages/common/locales "Common locales in the Angular repository") includes common locales. You can change your app's source locale for the build by setting the source locale in the `sourceLocale` field of your app's [workspace configuration](guide/workspace-config "Angular workspace configuration") file (`angular.json`). The build process (described in [Merge translations into the app](#merge) in this guide) uses your app's `angular.json` file to automatically set the [`LOCALE_ID`](api/core/LOCALE_ID "API reference for LOCALE_ID") token and load the locale data. +[Angular 的代码仓库中](https://github.com/angular/angular/tree/master/packages/common/locales "Angular 存储库中的常用语言环节")包含常见的本地环境。你可以通过在应用的[工作区配置](guide/workspace-config "Angular 工作空间配置")文件 `angular.json` 中的 `sourceLocale` 字段中设置源本地环境来为此构建更改应用的源本地环境。构建过程(在本指南的[把翻译合并到应用程序](#merge)中描述)会使用应用中的 `angular.json` 文件来自动设置 [`LOCALE_ID`](api/core/LOCALE_ID "LOCALE_ID 的 API 参考") 令牌并加载本地化数据。 + {@a i18n-pipes} ## Format data based on locale +## 根据本地环境格式化数据 + Angular provides the following built-in data transformation [pipes](guide/glossary#pipe "Definition of a pipe") that use the [`LOCALE_ID`](api/core/LOCALE_ID "API reference for LOCALE_ID") token to format data according to the locale's rules: +Angular 提供了下列内置数据转换[管道](guide/glossary#pipe "管道的定义") ,它们根据本地化的规则使用 [`LOCALE_ID`](api/core/LOCALE_ID "LOCALE_ID 的 API 参考") 令牌来格式化数据: + * [`DatePipe`](api/common/DatePipe): Formats a date value. + + [`DatePipe`](api/common/DatePipe):格式化日期值。 + * [`CurrencyPipe`](api/common/CurrencyPipe): Transforms a number to a currency string. + + [`CurrencyPipe`](api/common/CurrencyPipe):把数字转换成货币字符串。 + * [`DecimalPipe`](/api/common/DecimalPipe): Transforms a number into a decimal number string. + + [`DecimalPipe`](/api/common/DecimalPipe):把数字转换成十进制数的字符串。 + * [`PercentPipe`](api/common/PercentPipe): Transforms a number to a percentage string. + [`PercentPipe`](api/common/PercentPipe):把数字转换成百分比字符串。 + For example, `{{today | date}}` uses `DatePipe` to display the current date in the format for the locale in `LOCALE_ID`. +例如,`{{today | date}}` 使用 `DatePipe` 以 `LOCALE_ID` 中指定的本地化格式来显示当前日期。 + To override the value of `LOCALE_ID`, add the `locale` parameter. For example, to force the currency to use `en-US` no matter which language-locale you set for `LOCALE_ID`, use this form: `{{amount | currency : 'en-US'}}`. +要覆盖 `LOCALE_ID` 的值, 请添加 `locale` 参数。例如,要强制该货币使用 `en-US` 而不管你为 `LOCALE_ID` 设置的是哪种本地环境,请使用如下格式:`{{amount | currency : 'en-US'}}`。 + {@a Template-translations} ## Prepare templates for translations +## 准备翻译模板 + To translate your app's templates, you need to prepare the text for a translator or translation service by marking text, attributes, and other elements with the Angular `i18n` attribute. Follow these general steps: +要翻译你的应用模板,就要用 Angular 的 `i18n` 属性标记出文本、属性和其他元素来为翻译人员或翻译服务准备出文本。请遵循以下常规步骤: + 1. [Mark text for translations](#i18n-attribute). -2. [Add helpful descriptions and meanings](#help-translator) to help the translator with additional information or context. -3. [Translate text not for display](#no-element). -4. [Mark element attributes for translations](#translate-attributes), such as an image's `title` attribute. -5. [Mark plurals and alternates for translation](#plurals-alternates) in order to comply with the pluralization rules and grammatical constructions of different languages. + + [标记要翻译的文本](#i18n-attribute) 。 + +1. [Add helpful descriptions and meanings](#help-translator) to help the translator with additional information or context. + + [添加有用的描述和含义](#help-translator),以便为翻译人员提供额外的信息或背景信息。 + +1. [Translate text not for display](#no-element). + + [翻译不显示的文本](#no-element) 。 + +1. [Mark element attributes for translations](#translate-attributes), such as an image's `title` attribute. + + [标记要翻译的元素属性](#translate-attributes) ,比如图像的 `title` 属性。 + +1. [Mark plurals and alternates for translation](#plurals-alternates) in order to comply with the pluralization rules and grammatical constructions of different languages. + + [标记复数形式和替换形式以便翻译](#plurals-alternates),以符合不同语言的复数规则和语法结构。 {@a i18n-attribute} ### Mark text for translations +### 标记要翻译的文本 + Mark the static text messages in your component templates for translation using the `i18n` attribute. Place it on every element tag with fixed text to be translated. +使用 `i18n` 属性在组件模板中标记静态文本消息以进行翻译。把它放到每个带有要翻译的静态文本的元素标签上。 + For example, the following `

` tag displays a simple English language greeting, "Hello i18n!" +比如,下面的 `

` 标签会显示一个简单的英文问候语 “Hello i18n!”。 + To mark the greeting for translation, add the `i18n` attribute to the `

` tag. +要把这个问候语标记为要翻译的,请把 `i18n` 属性添加到 `

` 标签上。 +
@@ -167,110 +329,180 @@ To mark the greeting for translation, add the `i18n` attribute to the `

` tag `i18n` is a custom attribute, recognized by Angular tools and compilers. After translation, the compiler removes it. It is not an Angular directive. +`i18n` 是一个自定义属性,Angular 的工具和编译器都认识它。编译完成后,编译器会删除它。它并不是 Angular 中的指令。 +

{@a help-translator} ### Add helpful descriptions and meanings +### 添加有用的描述和含义 + To translate a text message accurately, the translator may need additional information or context. Add a _description_ of the text message as the value of the `i18n` attribute, as shown in the following example: +要准确翻译文本信息,翻译人员可能需要额外的信息或上下文。把此文本信息的*描述*添加为 `i18n` 属性的值,如下例所示: + The translator may also need to know the meaning or intent of the text message within this particular app context, in order to translate it the same way as other text with the same meaning. Start the `i18n` attribute value with the _meaning_ and separate it from the _description_ with the `|` character: `|`. +翻译人员可能还需要知道该特定应用上下文中,这段文本的意义或意图,以便像其它具有相同含义的文本一样翻译它。用带*含义*的 `i18n` 属性值开头,并用 `|` 字符把它和*描述*分隔开。 + For example, you can add the meaning that this `

` tag is a site header that needs to be translated the same way not only when used as a header, but also when referred to from another section of text: +例如,你可以添加这样的含义:`

` 标签是一个站点标头,它在用作标题时和从另一段文本中引用时都要翻译成一样的: + As a result, any text marked with `site header` as the _meaning_ is translated exactly the same way. +其结果是,任何标有 `site header` 的文字,都会翻译成完全相同的结果。 + {@a transaction-unit-ids}
+
How meanings control text extraction and merging
+
含义(meaning)如何控制文本的提取和合并
+ The Angular extraction tool (described in [Work with translation files](#ng-xi18n) in this guide) generates a translation unit entry for each `i18n` attribute in a template. It assigns each translation unit a unique ID based on the _meaning_ and _description_. +Angular 提取工具(在本指南的[“使用翻译文件”](#ng-xi18n)中讲解)会为模板中的每个 `i18n` 属性生成一个翻译单元条目。它会根据其*含义*和*描述*为每个翻译单元分配一个唯一的 ID。 + The same text elements with different _meanings_ are extracted with separate IDs. For example, if the word "right" appears with the meaning `correct` (as in "You are right") in one place, and with the meaning `direction` (as in "Turn right") in another place, the word is translated differently and merged back into the app as different translation entries. +要用不同的 ID 提取具有不同*含义*的文本元素。例如,如果单词 “right” 出现在一个地方时表示正确(比如:"You are right"),而在另一个地方的含义是方向(比如:"Turn right"),那么这个词的翻译就会有所不同,并且会作为不同的翻译条目合并回应用。 + If the same text elements have different _descriptions_ but the same _meaning_, they are extracted only once, with only one ID. That one translation entry is merged back into the app wherever the same text elements appear. +如果相同的文本元素具有不同的*描述*但*含义*相同,那么它们只会被提取一次,只有一个 ID。只要出现了相同的文本元素,就会把这个翻译条目合并回应用。 +
{@a no-element} ### Translate text not for display +### 翻译不显示的文字 + While you can translate non-displayed text using a `` tag, you are creating a new DOM element. To avoid doing so, wrap the text in an `` element, which is transformed into a non-displayed HTML comment as shown in this example: +虽然也可以使用 `` 标签来翻译未显示的文本,但这样你就会创建一个新的 DOM 元素。要避免这种情况,请把它放在 `` 元素中,该元素会被转换成一个不显示的 HTML 注释,如下例所示: + {@a translate-attributes} ### Mark element attributes for translations +### 标记要翻译的元素属性 + HTML attributes such as `title` include text that should be translated along with the rest of the displayed text in the template. The following example shows an image with a `title` attribute: +`title` 等 HTML 属性包含要与模板中的其它显示文本一起翻译的文本。下面的代码展示了一个带 `title` 属性的图片: + To mark an attribute for translation, add `i18n-`*attribute* in which *attribute* is the attribute to translate. The following example shows how to mark the `title` attribute on the `img` tag by adding `i18n-title`: +为了标记出要翻译的属性,就要为它添加一个 `i18n-`*属性名* 属性。下面的例子展示了如何通过添加 `i18n-title` 在 `img` 标签上标记出 `title` 属性: + You can use `i18n-`*attribute* with any attribute of any element. You also can assign a meaning, description, and custom ID with the `i18n-`*attribute*`="|@@"` syntax. +你可以对任意元素的任何属性添加 `i18n-`*属性名* 属性。你也可以用 `i18n-`*属性名*`="|@@"` 语法来为它指定含义、描述和自定义 ID。 + {@a plurals-alternates} ### Mark plurals and alternates for translation +### 标记复数形式和替换形式以便翻译 + Different languages have different pluralization rules and grammatical constructions that can make translation difficult. To simplify translation, use International Components for Unicode (ICU) clauses with regular expressions, such as `plural` to mark the uses of plural numbers, and `select` to mark alternate text choices. +不同的语言有不同的复数规则和语法结构,这会让翻译变得困难。要简化翻译,可以使用带有正则表达式的 Unicode 国际化组件(International Components for Unicode ICU)子句,比如 `plural` 标出要用的复数形式,用 `select` 标出候选的备用文字。 +
The ICU clauses adhere to the [ICU Message Format](http://userguide.icu-project.org/formatparse/messages "ICU Message Format") specified in the [CLDR pluralization rules](http://cldr.unicode.org/index/cldr-spec/plural-rules "Pluralization Rules"). +ICU 条款遵循 [CLDR 复数规则](http://cldr.unicode.org/index/cldr-spec/plural-rules "多元化规则")中指定的 [ICU 消息格式](http://userguide.icu-project.org/formatparse/messages "ICU 消息格式") 。 +
{@a plural-ICU} #### Mark plurals +#### 标出复数形式 + Use the `plural` clause to mark expressions that may not be meaningful if translated word-for-word. +使用 `plural` 子句来标出那些在逐字翻译时可能用不到的表达式。 + For example, if you want to display "updated x minutes ago" in English, you may want to display "just now", "one minute ago", or "_x_ minutes ago" (with _x_ as the actual number). Other languages might express this cardinality differently. The following example shows how to use a `plural` clause to express these three options: +比如,如果你想用英文显示 “updated x minutes ago”,你可能需要显示 “just now”、“one minute ago” 或 “ *x* minutes ago”( *x*为实际数字)。在其他语言中这种基数规则可能不同。下面的代码演示了如何使用 `plural` 子句来表达这三个选项: + In the above example: +在上面的例子中: + * The first parameter, `minutes`, is bound to the component property (`minutes`), which determines the number of minutes. + 第一个参数 `minutes` ,被绑定到组件的属性( `minutes` ),它决定了分钟数。 + * The second parameter identifies this as a `plural` translation type. + 第二个参数把它标识为 `plural` 翻译类型。 + * The third parameter defines a pattern of pluralization categories and their matching values: + + 第三个参数定义了复数分类模式以及与之匹配的值: + * For zero minutes, use `=0 {just now}`. + + 零分钟时,使用 `=0 {just now}` 。 + * For one minute, use `=1 {one minute}`. + + 一分钟后,使用 `=1 {one minute}` 。 + * For any unmatched cardinality, use `other {{{minutes}} minutes ago}`. You can use HTML markup and [interpolations](guide/glossary#interpolation "Definition of interpolation") such as `{{{minutes}}` with the `plural` clause in expressions. + + 对于任何无法匹配的基数,使用 `other {{{minutes}} minutes ago}` 。你还可以使用表达式中带有 `plural` 子句的 HTML 标记和[插值](guide/glossary#interpolation "插值的定义") ,比如 `{{{minutes}}`。 + * After the pluralization category, put the default text (English) within braces (`{}`). + 在复数类别后面,把默认文本(英文)放在花括号(`{}`)中。 + Pluralization categories include (depending on the language): +复数类别包括(取决于语言): + * `=0` (or any other number) + + `=0`(或任何其他数字) + * `zero` * `one` * `two` @@ -279,12 +511,17 @@ Pluralization categories include (depending on the language): * `other`
+
Locales may not support some pluralization categories
+
本地环境可能不支持某些复数类别
+ Many locales don't support some of the pluralization categories. For example, the default locale (`en-US`) and other locales (such as `es`) have very simple `plural()` functions that don't support the `few` category. The following shows the [en-US](https://github.com/angular/angular/blob/ecffc3557fe1bff9718c01277498e877ca44588d/packages/core/src/i18n/locale_en.ts#L15-L18) `plural()` function: +很多本地环境都不支持某些复数类别。例如,默认本地环境( `en-US` )和其他本地环境(例如 `es` )都有非常简单的 `plural()` 函数,它们不支持这 `few` 类别。 [en-US](https://github.com/angular/angular/blob/ecffc3557fe1bff9718c01277498e877ca44588d/packages/core/src/i18n/locale_en.ts#L15-L18) 的 `plural()` 函数实例如下: + ``` function plural(n: number): number { let i = Math.floor(Math.abs(n)), v = n.toString().replace(/^[^.]*\.?/, '').length; @@ -298,8 +535,12 @@ The `few` category will never match. If none of the pluralization categories match, Angular will try to match `other`. Use `other` as the standard fallback for a missing category. +该函数只返回 1(`one`)或 5(`other`)。这个 `few` 类别永远不会匹配。如果所有复数类别都不匹配,Angular 就会尝试匹配 `other` 类别。`other` 用作缺失类别的标准后备。 + For more information about pluralization categories, see [Choosing plural category names](http://cldr.unicode.org/index/cldr-spec/plural-rules#TOC-Choosing-Plural-Category-Names) in the CLDR - Unicode Common Locale Data Repository. +有关复数类别的详细信息,请参阅 “CLDR - Unicode 公共本地化数据存储库”中的[选择复数类别名称](http://cldr.unicode.org/index/cldr-spec/plural-rules#TOC-Choosing-Plural-Category-Names) 。 +
{@a select-ICU} @@ -307,17 +548,25 @@ For more information about pluralization categories, see [Choosing plural catego ### Mark alternates and nested expressions +### 标记替代表达式和嵌套表达式 + If you need to display alternate text depending on the value of a variable, you need to translate all of the alternates. +如果需要根据变量的值来显示备用文本,你需要翻译所有的备用项。 + The `select` clause, similar to the `plural` clause, marks choices for alternate text based on your defined string values. For example, the following clause in the component template binds to the component's `gender` property, which outputs one of the following string values: "male", "female" or "other". The clause maps those values to the appropriate translations: +`select` 子句类似于 `plural` 子句,它会根据你定义的字符串值来标记出备用文本的可选值。例如,组件模板中的下列子句绑定了组件的 `gender` 属性,该属性输出以下字符串值之一:“male”、“female” 或 “other”。该子句将这些值映射成适当的翻译: + You can also nest different clauses together, such as the `plural` and `select` clauses in the following example: +你还可以把不同的子句嵌套在一起,比如下例中的 `plural` 和 `select` 子句: + @@ -327,47 +576,86 @@ You can also nest different clauses together, such as the `plural` and `select` ## Work with translation files +## 使用翻译文件 + After preparing a template for translation, use the Angular CLI `xi18n` command to extract the marked text in the template into a _source language_ file. The marked text includes text marked with `i18n` and attributes marked with `i18n-`*attribute* as described in the previous section. Follow these steps: +在准备好要翻译的模板后,使用 Angular CLI 的 `xi18n` 命令把模板中标记过的文本提取到*源语言*文件中。所谓标记过的文本包括标有 `i18n` 的文本和标有 `i18n-`*属性名* 的属性,如前一节中所描述。请执行以下步骤: + 1. [Extract the source language file](#create-source). You can optionally change the location, format, and name. + + [提取源语言文件](#create-source) 。你可以选择更改位置、格式和名称。 + 2. [Create a translation file for each language](#localization-folder) by copying the source language file. + + 通过复制源语言文件,可以[为每种语言创建一个翻译文件](#localization-folder)。 + 3. [Translate each translation file](#translate-text-nodes). + + [翻译每个翻译文件](#translate-text-nodes) 。 + 4. [Translate plurals and alternate expressions](#translate-plural-select) separately. + 单独[翻译复数形式和替代表达式](#translate-plural-select) 。 + {@a create-source} ### Extract the source language file +### 提取源语言文件 + To extract the source language file, open a terminal window, change to the root directory of your app project, and run the following CLI command: +要提取源语言文件,请打开终端窗口,切换到应用项目的根目录,执行以下 CLI 命令: + ng xi18n The `xi18n` command creates a source language file named `messages.xlf` in your project's root directory using the [XML Localization Interchange File Format (XLIFF, version 1.2)](https://en.wikipedia.org/wiki/XLIFF "Wikipedia page about XLIFF"). +`xi18n` 命令使用 [XML 本地化交换文件格式(XLIFF 版本 1.2)](https://en.wikipedia.org/wiki/XLIFF "关于 XLIFF 的维基百科页面")在项目的根目录下创建一个名为 `messages.xlf` 的源语言文件。 + Use the following `xi18n` command options to change the source language file location, format, and file name: +使用下列 `xi18n` 命令可以改变源语言文件的位置、格式和文件名: + * `--output-path`: Change the location. + + `--output-path`:改变位置。 + * `--format`: Change the format. + + `--format`:改变格式。 + * `--outFile`: Change the file name. + `--outFile`:改变文件名。 + Note: The `--i18n-locale` option is deprecated. Angular 9 uses the source locale configured in your app's [workspace configuration](guide/workspace-config "Angular workspace configuration") file (`angular.json`). +注意:`--i18n-locale` 选项已弃用。 Angular 9 会使用应用的[工作空间配置](guide/workspace-config "Angular 工作空间配置")文件( `angular.json` )中[配置](guide/workspace-config "Angular 工作空间配置")的源本地环境。 +
The ng xi18n extraction mechanism uses the ViewEngine compiler, which is not able to cope with some code syntax that the Ivy compiler can handle. A fix for this issue is currently under development. To follow or contribute to this fix see [PR 32912](https://github.com/angular/angular/pull/32912). +ng xi18n 提取机制使用的是 ViewEngine 编译器,它无法处理 Ivy 编译器可以处理的一些代码语法。这个问题的解决方案目前正在开发中。要跟踪修复进度或做出贡献,请参阅 [PR 32912](https://github.com/angular/angular/pull/32912) 。 +
#### Change the source language file location +#### 修改源语言文件的位置 + To create a file in the `src/locale` directory, specify the output path as an option, as shown in the following example: +要把文件创建在 `src/locale` 目录下,请把输出路径指定为一个选项,如下例所示: + ng xi18n --output-path src/locale @@ -376,14 +664,25 @@ To create a file in the `src/locale` directory, specify the output path as an op #### Change the source language file format +#### 修改源语言文件格式 + The `xi18n` command can read and write files in three translation formats: +`xi18n` 命令可以用三种翻译格式读写文件: + * XLIFF 1.2 (default) + + XLIFF 1.2(默认) + * XLIFF 2 * [XML Message Bundle (XMB)](http://cldr.unicode.org/development/development-process/design-proposals/xmb) + [XML 消息包(XMB)](http://cldr.unicode.org/development/development-process/design-proposals/xmb) + Specify the translation format explicitly with the `--format` command option, as shown in the following examples: +使用 `--format` 命令选项显式指定转换格式,如下例所示: + ng xi18n --format=xlf ng xi18n --format=xlf2 @@ -395,13 +694,19 @@ ng xi18n --format=xmb XLIFF files use the extension `.xlf`. The XMB format generates `.xmb` source language files but uses`.xtb` (XML Translation Bundle: XTB) translation files. + XLIFF 文件使用扩展名 `.xlf`。 XMB 格式生成 `.xmb` 源语言文件,但使用 `.xtb`(XML Translation Bundle:XTB)翻译文件。 + #### Change the source language file name +#### 修改源语言文件名 + To change the name of the source language file generated by the extraction tool, use the `--outFile` command option: +要更改提取工具生成的源语言文件的名称,请使用 `--outFile` 命令选项: + ng xi18n --out-file source.xlf @@ -410,43 +715,77 @@ the `--outFile` command option: ### Create a translation file for each language +### 为每种语言创建一个翻译文件 + The `ng xi18n` command (with no options) generates a source language file named `messages.xlf` in the project `src` folder. Create *translation* files for each language by copying the source language file. To avoid confusion with multiple translations, you should organize the language translation files by locale in a dedicated `locale` folder under `src/`. Use a filename extension that matches the associated locale, such as `messages.fr.xlf`. +`ng xi18n` 命令(不带选项时)会在项目的 `src` 文件夹下生成一个名为 `messages.xlf` 的源语言文件。通过复制源语言文件为每种语言创建一个*翻译*文件。为了避免混淆这么多翻译文件,你应该把这些语言的翻译文件整理到 `src/` 下的一个专用 `locale` 文件夹中。这些文件使用与相关的本地环境匹配的扩展名,例如 `messages.fr.xlf` 。 + For example, to create a French translation file, follow these steps: +例如,要创建法语翻译文件,请按照下列步骤操作: + 1. Make a copy of the `messages.xlf` source language file. + + 复制一下 `messages.xlf` 源语言文件。 + 2. Put the copy in the `src/locale` folder. + + 把这份副本放在 `src/locale` 文件夹中。 + 3. Rename the copy to `messages.fr.xlf` for the French language (`fr`) translation. Send this translation file to the translator. + 把该副本重命名为 `messages.fr.xlf` 以便进行法语( `fr` )翻译。把这个翻译文件发给翻译人员。 + Repeat the above steps for each language you want to add to your app. +针对要添加到应用中的每种语言,重复上述步骤。 + {@a translate-text-nodes} ### Translate each translation file +### 翻译各个翻译文件 + Unless you are fluent in the language and have the time to edit translations, you would likely send each translation file to a translator, who would then use an XLIFF file editor to create and edit the translation. +除非你能流利的说那种语言并且有时间编辑这些翻译文件,否则很可能要把每个翻译文件都发给翻译人员,翻译人员会使用 XLIFF 文件编辑器来创建和编辑翻译。 + To demonstrate this process, see the `messages.fr.xlf` file in the , which includes a French translation you can edit without a special XLIFF editor or knowledge of French. Follow these steps: +要演示这个过程,请参阅中的 `messages.fr.xlf` 文件,它包含法语翻译,无需特殊的 XLIFF 编辑器或法语知识,即可编辑。请执行以下步骤: + 1. Open `messages.fr.xlf` and find the first `` element. This is a *translation unit*, also known as a *text node*, representing the translation of the `

` greeting tag that was previously marked with the `i18n` attribute: + 打开 `messages.fr.xlf` 并找到第一个 `` 元素。这是一个*翻译单元* ,也叫做*文本节点*,代表对之前标记过 `i18n` 属性的 `

` 标签的翻译: + > > The `id="introductionHeader""` is a [custom ID](#custom-id "Manage marked text with custom IDs"), but without the `@@` prefix required in the source HTML. +> +> `id="introductionHeader""` 是一个[自定义 ID](#custom-id "用自定义 ID 管理带标记的文本") ,但在源 HTML 中没有 `@@` 前缀。 +> 2. Duplicate the `...` element in the text node, rename it `target`, and then replace its content with the French text: + 在文本节点中复制 `...` 元素,把它重命名为 `target` 元素,然后用法语文本替换它的内容: + > > In a more complex translation, the information and context in the [description and meaning elements](#help-translator "Add helpful descriptions and meanings") described previously would help you choose the right words for translation. +> +> 在更复杂的翻译中,以前讲过的[描述(description)和含义(meaning)](#help-translator "添加有用的描述和含义")中提供的信息和上下文可以帮助你选择合适的单词进行翻译。 +> 3. Translate the other text nodes the same way as shown in the following example: + 翻译其他文本节点的方式与下例所示相同: + >
@@ -456,46 +795,78 @@ Follow these steps: If you change either the text or the meaning, then the `id` changes. For more about managing text updates and IDs, see the previous section on [custom IDs](#custom-id "Manage marked text with custom IDs"). + 不要更改翻译单元的 ID。每个 `id` 都是由 Angular 生成的,取决于模板文本的内容及其指定的含义。如果你改变了文本或含义,那么 `id` 就会改变。有关管理文本更新和 ID 的更多信息,请参阅上一节的[自定义 ID](#custom-id "用自定义 ID 管理带标记的文本") 。 +
{@a translate-plural-select} ### Translate plurals and alternate expressions +### 翻译复数和替代表达式 + The [`plural` and `select` ICU expressions](#plurals-alternates "Mark plurals and alternates for translation") are extracted as additional messages, so you must translate them separately. +[`plural` 和 `select`](#plurals-alternates "标记复数形式和替换形式以进行翻译")的[`plural` ICU 表达式](#plurals-alternates "标记复数形式和替换形式以进行翻译")作为附加信息被提取出来,因此你必须单独翻译它们。 + +{@a translate-plural} + {@a translate-plural} #### Translate plurals +#### 翻译复数 + To translate a `plural`, translate its ICU format match values as shown in the following example: +要翻译 `plural` ,请把它的 ICU 格式匹配值翻译成下面的例子: + * `just now` + + `just now` + * `one minute ago` + + `one minute ago` + * ` minutes ago` + ` minutes ago` + You can add or remove plural cases as needed for each language. +你可以根据需要为每种语言添加或移除多个 case。 +
For language plural rules, see [CLDR plural rules](http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html "CLDR Charts to view the Common Locale Data Repository data"). +对于语言复数规则,参见[CLDR 复数规则](http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html "CLDR 图表用于查看 Common Locale Data Repository 数据") 。 +
{@a translate-select} +{@a translate-select} + #### Translate alternate expressions +#### 翻译替代表达式 + Angular also extracts alternate `select` ICU expressions as separate translation units. The following shows a `select` ICU expression in the component template: +Angular 还提供了另一种 `select` ICU(Unicode 国际化组件)表达式作为单独的翻译单元。下图显示了组件模板中的一个 `select` ICU 表达式: + In this example, Angular extracts the expression into two translation units. The first contains the text outside of the `select` clause, and uses a placeholder for `select` (``): +在这个例子中,Angular 把此表达式提取成了两个翻译单元。第一个单元包含 `select` 子句外的文本,并使用了一个 `select` 占位符( `` ): +
@@ -503,30 +874,44 @@ In this example, Angular extracts the expression into two translation units. The When translating the text, you can move the placeholder if necessary, but don't remove it. If you remove the placeholder, the ICU expression will not appear in your translated app. +在翻译文本时,你可以根据需要移动这个占位符,但不能删除它。如果你删除了占位符,这个 ICU 表达式就不会出现在翻译后的应用中。 +
The second translation unit contains the `select` clause: +第二个翻译单元包含 `select` 子句: + The following example shows both translation units after translating: +下面的例子展示了翻译过的翻译单元: + {@a translate-nested} #### Translate nested expressions +#### 翻译嵌套表达式 + Angular treats a nested expression in the same manner as an alternate expression, extracting it into two translation units. The first contains the text outside of the nested expression: +Angular 对嵌套表达式的处理方式和替代表达式一样,会把它提取成两个翻译单元。第一个包含嵌套表达式外部的文本: + The second translation unit contains the complete nested expression: +第二个翻译单元包含完整的嵌套表达式: + The following example shows both translation units after translating: +下面的例子展示了翻译后的翻译单元: + {@a merge} @@ -534,21 +919,31 @@ The following example shows both translation units after translating: ## Merge translations into the app +## 把翻译合并到应用中 + To merge the completed translations into the app, use the [Angular CLI](guide/glossary#command-line-interface-cli "Definition of CLI") to build a copy of the app's distributable files for each locale. The build process replaces the original text with translated text, and sets the `LOCALE_ID` token for each distributable copy of the app. It also loads and registers the locale data. +要把已完成的译文合并到应用中,请使用 [Angular CLI](guide/glossary#command-line-interface-cli "CLI 的定义") 为每个本地环境构建应用的可分发副本。构建过程中会用翻译文本替换原始文本,并为应用的每个可分发副本设置 `LOCALE_ID` 令牌。它还会加载并注册本地化数据。 + After merging, you can serve each distributable copy of the app using server-side language detection or different subdirectories, as described in the next section about [deploying multiple locales](#deploy-locales). +合并之后,你可以使用服务器端的语言检测功能或使用不同的子目录来为应用的每个可分发副本架设服务,就像下一章中[部署多个本地环境](#deploy-locales)部分描述的那样。 + The build process uses [ahead-of-time (AOT) compilation](guide/glossary#ahead-of-time-aot-compilation) to produce a small, fast, ready-to-run app. With Ivy in Angular version 9, AOT is used by default for both development and production builds, and AOT is required to localize component templates. +此构建过程会用[预先(AOT)编译](guide/glossary#ahead-of-time-aot-compilation)来生成一个小巧、快速、可立即运行的应用。在 Angular 9 的 Ivy 中,AOT 默认用于开发版本和生产版本,并且需要 AOT 来对组件模板进行本地化。 +
For a detailed explanation the build process, see [Building and serving Angular apps](guide/build "Building and serving Angular apps"). This build process works for translation files in the `.xlf` format or in another format that Angular understands, such as `.xtb`. +有关构建过程的详细解说,请参阅[构建和提供 Angular 应用](guide/build "构建和提供 Angular 应用")。这个构建过程可用于 `.xlf` 格式的翻译文件或 Angular 能理解的其它格式,比如 `.xtb` 。 +
@@ -556,31 +951,50 @@ This build process works for translation files in the `.xlf` format or in anothe Ivy does not support merging i18n translations when using JIT mode. If you [disable Ivy](guide/ivy#opting-out-of-ivy-in-version-9) and are using JIT mode, see [merging with the JIT compiler](https://v8.angular.io/guide/i18n#merge-with-the-jit-compiler "Merge with the JIT compiler"). +在使用 JIT 模式时,Ivy 不支持合并 i18n 的翻译。如果你[禁用了 Ivy](guide/ivy#opting-out-of-ivy-in-version-9) 并正在使用 JIT 模式,请参阅[合并 JIT 编译器](https://v8.angular.io/guide/i18n#merge-with-the-jit-compiler "与 JIT 编译器合并") 。 +
To build a separate distributable copy of the app for each locale, [define the locales in the build configuration](#localize-config) in your project's workspace configuration file [`angular.json`](guide/workspace-config "Angular workspace configuration"). This method shortens the build process by removing the requirement to perform a full app build for each locale. +要为每个本地环境构建应用的一个可分发副本,请在项目工作空间配置文件 [`angular.json`](guide/workspace-config "Angular 工作空间配置") 中的[构建配置](#localize-config)中[定义本地环境](#localize-config)。这个方法通过放弃为每个本地环境执行完整构建的需求,缩短了构建过程。 + You can then [generate app versions for each locale](#localize-generate) using the `"localize"` option in `angular.json`. You can also [build from the command line](#localize-build-command) using the Angular CLI [`build`](/cli/build "CLI reference for ng build") command with the `--localize` option. +然后,你可以使用 `angular.json` 中的 `"localize"` 选项[为每个本地环境生成一个应用版本](#localize-generate) 。您也可以使用 Angular CLI [`build`](/cli/build "ng build 的 CLI 引用")命令及其 `--localize` 选项来[进行命令行构建](#localize-build-command)。 +
You can optionally [apply specific build options for just one locale](#localize-build-one-locale) for a custom locale configuration. +你也可以选择[只针对一种本地环境来应用的特定构建选项](#localize-build-one-locale)配置自定义本地环境。 +
{@a localize-config} ### Define locales in the build configuration +### 在构建配置中定义本地环境 + Use the `i18n` project option in your app's build configuration file ([`angular.json`](guide/workspace-config "Angular workspace configuration")) to define locales for a project. The following sub-options identify the source language and tell the compiler where to find supported translations for the project: +在应用的构建配置( [`angular.json`](guide/workspace-config "Angular 工作空间配置") )中使用 `i18n` 项目选项来定义项目的本地环境。它下面的子选项用于标识源语言,并告诉编译器要在哪里找到该项目支持的各种翻译: + * `sourceLocale`: The locale you use within the app source code (`en-US` by default) + + `sourceLocale`:你在应用源代码中使用的本地环境(默认为 `en-US` ) + * `locales`: A map of locale identifiers to translation files + `locales`:本地环境标识符到翻译文件的映射表 + For example, the following excerpt of an `angular.json` file sets the source locale to `en-US` and provides the path to the `fr` (French) locale translation file: +例如,下面的 `angular.json` 文件片段把源本地环境设置为 `en-US` 并提供了到 `fr`(法语)本地环境翻译文件的路径: + ... "projects": { @@ -602,21 +1016,37 @@ For example, the following excerpt of an `angular.json` file sets the source loc ### Generate app versions for each locale +### 为每种本地环境生成一个应用版本 + To use your locale definition in the build configuration, use the `"localize"` option in `angular.json` to tell the CLI which locales to generate for the build configuration: +要在构建配置中使用你的本地环境定义,请使用 `angular.json` 的 `"localize"` 选项告诉 CLI 要为此构建配置生成哪些本地环境: + * Set `"localize"` to `true` for *all* the locales previously defined in the build configuration. + + 对于以前在构建配置中定义的*所有*本地环境,*都要*把 `"localize"` 设置为 `true`。 + * Set `"localize"` to an array of a subset of the previously-defined locale identifiers to build only those locale versions. + + 将 `"localize"` 设置为预定义的本地环境标识符子集的数组,来要求只构建那些本地环境版本。 + * Set `"localize"` to `false` to disable localization and not generate any locale-specific versions. + 将 `"localize"` 设置为 `false` 表示禁用本地化,不生成任何特定于本地环境的版本。 +
Note: [Ahead-of-time (AOT) compilation](guide/glossary#ahead-of-time-aot-compilation) is required to localize component templates. If you changed this setting, set `"aot"` to `true` in order to use AOT. +注意:本地化组件模板需要进行[预先(AOT)编译](guide/glossary#ahead-of-time-aot-compilation)。如果更改了此设置,请将 `"aot"` 设置为 `true`,以便使用 AOT。 +
The following example shows the `"localize"` option set to `true` in `angular.json` so that all locales defined in the build configuration are built: +下面的例子展示了在 `angular.json` 中把 `"localize"` 选项设为 `true`,以便在构建配置中定义所有的本地环境: + "build": { "builder": "@angular-devkit/build-angular:browser", @@ -632,21 +1062,31 @@ Due to the deployment complexities of i18n and the need to minimize rebuild time Setting the `"localize"` option to `true` will cause an error when using `ng serve` if more than one locale is defined. Setting the option to a specific locale, such as `"localize": ["fr"]`, can work if you want to develop against a specific locale (such as `fr`). +由于 i18n 的部署复杂性以及最小化重建时间的需要,开发服务器一次只支持一个本地环境的本地化。如果定义了多个本地环境,那么当使用 `ng serve` 时,把 `"localize"` 选项设置为 `true` 就会导致错误。如果你想针对特定的本地环境(比如 `fr` )进行开发,只要把这个选项设置为特定的本地环境(比如 `"localize": ["fr"]`)就可以了。 + The CLI loads and registers the locale data, places each generated version in a locale-specific directory to keep it separate from other locale versions, and puts the directories within the configured `outputPath` for the project. For each application variant the `lang` attribute of the `html` element is set to the locale. The CLI also adjusts the HTML base HREF for each version of the app by adding the locale to the configured `baseHref`. +CLI 会加载并注册本地化数据,把生成的每个版本都放在一个特定本地环境的目录下,以保证它与其它本地版本分开,并把这些目录放在所配置的 `outputPath` 中。对于应用的每个变体, `html` 元素的 `lang` 属性都会设置为这个本地环境。 CLI 还会通过在所配置的 `baseHref` 上添加本地环境,来为每个版本的应用调整 HTML 的 base HREF。 + You can set the `"localize"` property as a shared configuration that all the configurations effectively inherit (or can override). +你可以把 `"localize"` 属性设置为所有配置都能有效继承(或可覆盖)的共享配置。 + {@a localize-build-command} ### Build from the command line +### 从命令行构建 + You can also use the `--localize` option with the [`ng build`](/cli/build "CLI reference for ng build") command and your existing `production` configuration. The CLI builds all locales defined in the build configuration, which is similar to setting the `"localize"` option to `true` as described in the previous section. +你还可以将 `--localize` 选项与 [`ng build`](/cli/build "ng build 的 CLI 参考手册") 命令和现有的 `production` 配置一起使用。 CLI 会构建在构建配置中定义的所有本地环境,类似于把 `"localize"` 选项设置为 `true` ,如上一节所述。 + ng build --prod --localize @@ -655,8 +1095,12 @@ The CLI builds all locales defined in the build configuration, which is similar ### Apply specific build options for just one locale +### 只针对一种本地环境应用特定的构建选项 + To apply specific build options to only one locale, you can create a custom locale-specific configuration by specifying a single locale as shown in the following example: +要想只为一个本地环境应用特定的构建选项,你可以通过指定一个本地环境来创建一个特定于本地环境的自定义配置,如下例所示: + "build": { ... @@ -683,6 +1127,8 @@ To apply specific build options to only one locale, you can create a custom loca You can then pass this configuration to the `ng serve` or `ng build` commands. The following shows how to serve the French language file created in the example for this guide: +然后,你可以将此配置文件传给 `ng serve` 或 `ng build` 命令。下面展示了如何在本指南的例子中使用该语言文件启动开发服务器: + ng serve --configuration=fr @@ -691,10 +1137,14 @@ The following shows how to serve the French language file created in the example You can use the CLI development server (`ng serve`), but only with a single locale. +你可以使用 CLI 开发服务器( `ng serve` ),但只能使用一个本地环境。 + For production builds, you can use configuration composition to execute both configurations: +对于生产环境构建,你可以通过配置组合来执行这两种配置: + ng build --configuration=production,fr @@ -733,16 +1183,30 @@ For production builds, you can use configuration composition to execute both con ### Report missing translations +### 报告遗漏的翻译 + When a translation is missing, the build succeeds but generates a warning such as `Missing translation for message "foo"`. You can configure the level of warning that is generated by the Angular compiler: +如果缺少某个翻译,那么编译就会成功,但会生成一条警告,比如 `Missing translation for message "foo"`。你可以配置 Angular 编译器所生成的警告级别: + * `error`: Throw an error. If you are using AOT compilation, the build will fail. -If you are using JIT compilation, the app will fail to load. + If you are using JIT compilation, the app will fail to load. + + `error`:抛出一个错误。如果你正在使用 AOT 编译,那么构建就会失败。如果你正在使用 JIT 编译,该应用将无法加载。 + * `warning` (default): Show a `Missing translation` warning in the console or shell. + + `warning`(默认值):在控制台或 shell 中显示 `Missing translation` 警告。 + * `ignore`: Do nothing. + `ignore`:什么都不做 + Specify the warning level in the `options` section for the `build` target of your Angular CLI configuration file (`angular.json`). The following example shows how to set the warning level to `error`: +在 Angular CLI 配置文件( `angular.json` )中 `build` 下的 `options` 部分指定警告级别。下面的代码展示了如何把警告级别设置为 `error` : + "options": { ... @@ -754,10 +1218,16 @@ Specify the warning level in the `options` section for the `build` target of you ## Deploy multiple locales +## 部署多个本地环境 + If `myapp` is the directory containing your app's distributable files, you would typically make available different versions for different locales in locale directories such as `myapp/fr` for the French version and `myapp.com/es` for the Spanish version. +如果 `myapp` 是那个包含应用分发文件的目录,那么你通常可以在每个本地化目录中为不同的本地环境提供不同的版本,比如 `myapp/fr`(法语版)和 `myapp.com/es`(西班牙语版)。 + The HTML `base` tag with the `href` attribute specifies the base URI, or URL, for relative links. If you set the `"localize"` option in `angular.json` to `true` or to an array of locale IDs, the CLI adjusts the base `href` for each version of the app by adding the locale to the configured `"baseHref"`. You can specify the `"baseHref"` for each locale in your workspace configuration file (`angular.json`), as shown in the following example, which sets `"baseHref"` to an empty string: +带有 `href` 属性的 HTML `base` 标签为相对链接指定了基址 URI 或 URL。如果你把 `angular.json` 中的 `"localize"` 选项设置为 `true` 或者设置了一个本地环境 ID 的数组,那么 CLI 就会通过把该本地环境 ID 添加到已配置的 `"baseHref"` 中来为每个应用版本修正 `base href`。你可以在工作区的配置文件(`angular.json` )中为每个本地环境指定 `"baseHref"`,比如下面的例子中,这个 `"baseHref"` 被设置为空字符串: + ... "projects": { @@ -778,15 +1248,23 @@ The HTML `base` tag with the `href` attribute specifies the base URI, or URL, fo You can also use the CLI `--baseHref` option with [`ng build`](cli/build "CLI reference for ng build") to declare the base `href` at compile time. +您也可以在编译时使用 CLI 的 `--baseHref` 选项与 [`ng build`](cli/build "ng build 的 CLI 引用") 声明 `base href`。 + Configuring servers for hosting multiple locales is outside the scope of this guide. For details on how to deploy apps to a remote server, see [Deployment](guide/deployment "Deployment guide"). +如何配置托管多种本地环境的服务器超出了本指南的范围。关于如何将应用部署到远程服务器的详细信息,请参见[部署](guide/deployment "部署指南")指南。 + {@a app-pre-translation} ## Explore the translated example app +## 浏览已翻译的范例应用 + The following tabs show the example app and its translation files: +下面显示了该应用及其翻译文件的示例: + @@ -802,37 +1280,66 @@ The following tabs show the example app and its translation files: ## Optional practices +## 可选实践 + The following are optional practices that may be required in special cases: +以下是特殊情况下可能会用到的一些可选实践: + * [Set the source locale manually](#set-source-manually) by setting the [LOCALE_ID](https://angular.io/api/core/LOCALE_ID "API reference for LOCALE_ID") token. + + 通过设置 [LOCALE_ID](https://angular.io/api/core/LOCALE_ID "LOCALE_ID 的 API 参考") 令牌来[手动设置源本地环境](#set-source-manually) 。 + * [Import global variants of the locale data](#import-locale) for extra locale data. + + 为其他本地化数据[导入本地化数据的全局变种](#import-locale) 。 + * [Manage marked text with custom IDs](#custom-id) if you require more control over matching translations. + 如果你想翻译内容的匹配工作有更多的控制权,可以[使用自定义 ID 来管理](#custom-id)。 + {@a set-source-manually} ### Set the source locale manually +### 手动设置源本地环境 + Angular already contains locale data for `en-US`. The Angular CLI automatically includes the locale data and sets the `LOCALE_ID` value when you use the `--localize` option with [`ng build`](cli/build "ng build description"). +Angular 已经包含了 `en-US` 本地化数据。在使用 [`ng build`](cli/build "ng build description") 的 `--localize` 选项时,Angular CLI 会自动包含本地化数据并设置 `LOCALE_ID` 的值。 + To manually set an app's source locale to one other than the automatic value, follow these steps: +若要手动将应用的源本地环境设置为自动包含的值以外的本地环境,请执行以下步骤: + 1. Look up the ID for the language-locale combination in [the Angular repository](https://github.com/angular/angular/tree/master/packages/common/locales "Common locales in the Angular repository"). + + 在 [Angular 的代码仓库中](https://github.com/angular/angular/tree/master/packages/common/locales "Angular 存储库中的常用语言环节")查找此本地环境组合的 ID。 + 2. Set the [`LOCALE_ID`](api/core/LOCALE_ID "API reference for LOCALE_ID") token. The following example sets the value of `LOCALE_ID` to `fr` (French): + 设置 [`LOCALE_ID`](api/core/LOCALE_ID "LOCALE_ID 的 API 参考") 令牌。下面的例子中把 `LOCALE_ID` 的值设置为 `fr`(法语): + {@a import-locale} ### Import global variants of the locale data +### 导入本地化数据的全局变体 + Angular will automatically include locale data if you configure the locale using the `--localize` option with [`ng build`](cli/build "ng build description") CLI command. +如果使用带有 `--localize` 选项的 CLI 命令 [`ng build`](cli/build "ng build description") 来配置本地环境,Angular 就会自动包含本地化数据。 + The [Angular repository](https://github.com/angular/angular/tree/master/packages/common/locales "Common locales in the Angular repository") files (`@angular/common/locales`) contain most of the locale data that you need, but some advanced formatting options require additional locale data. Global variants of the locale data are available in [`@angular/common/locales/global`](https://github.com/angular/angular/tree/master/packages/common/locales/global "Global locale variants in the Angular repository"). The following example imports the global variants for French (`fr`): +[Angular 的代码仓库](https://github.com/angular/angular/tree/master/packages/common/locales "Angular 存储库中的常用语言环节") 中的一些文件( `@angular/common/locales` )包含了你需要的大部分本地化数据,但是一些高级的格式化选项需要提供额外的本地化数据。本地化数据的全局变体可以在 [`@angular/common/locales/global`](https://github.com/angular/angular/tree/master/packages/common/locales/global "Angular 存储库中的全局本地环境变体") 下找到。下面的例子导入了法语( `fr` )的全局变体: + import '@angular/common/locales/global/fr; @@ -841,51 +1348,77 @@ import '@angular/common/locales/global/fr; ### Manage marked text with custom IDs +### 用自定义 ID 管理标记过的文本 + The Angular extractor generates a file with a translation unit entry for each `i18n` attribute in a template. As described previously (in [How meanings control text extraction and merging](#transaction-unit-ids)), Angular assigns each translation unit a unique ID such as the following: +Angular 的提取器会为模板中的每个 `i18n` 属性生成一个带翻译单元条目的文件。如前所述(在[控制文本的提取和合并方式](#transaction-unit-ids)中),Angular 会为每个翻译单元分配一个唯一的 ID,如下所示: + When you change the translatable text, the extractor generates a new ID for that translation unit. In most cases a text change would also require a change to the translation. Therefore, using a new ID keeps the text change in sync with translations. +当你修改要翻译的文本时,提取器会为那个翻译单元生成一个新的 ID。在大多数情况下,对文本的更改也确实需要更改翻译。因此,使用新 ID 会使文本更改与翻译保持同步。 + However, some translation systems require a specific form or syntax for the ID. To address this requirement, you can mark text with _custom_ IDs. While most developers don't need to use custom IDs, some may want to use IDs that have a unique syntax to convey additional metadata (such as the library, component, or area of the app in which the text appears). +但是,某些翻译系统需要 ID 满足特定的格式或语法。为满足这一需求,你可以用*自定义* ID 来标记文本。虽然大多数开发人员不需要使用自定义 ID,但有些开发人员可能希望使用具有独特语法的 ID 来传递额外的元数据(例如应用中的库、组件或应用范围)。 + Specify a custom ID in the `i18n` attribute by using the prefix `@@`. The following example defines the custom ID `introductionHeader`: +使用前缀 `@@` 可以在 `i18n` 属性中指定自定义 ID。下面的例子定义了自定义 ID `introductionHeader` : + When you specify a custom ID, the extractor generates a translation unit with the custom ID: +当你指定一个自定义 ID 时,提取器会生成一个带有自定义 ID 的翻译单元: + If you change the text, the extractor does *not* change the ID. As a result, you don't have to take the extra step of updating the translation. The drawback of using custom IDs is that if you change the text, your translation may be out-of-sync with the newly changed source text. +如果改变了文本,提取器就*不会*修改 ID。因此,您无需采取额外步骤来更新翻译。使用自定义 ID 的一个缺点是,如果你修改了文本,你的翻译可能会与新修改过的源文本不同步。 + #### Use a custom ID with a description +#### 使用带描述的自定义 ID + Use a custom ID in combination with a description and a meaning to further help the translator. The following example includes a description, followed by the custom `id`: +使用自定义 ID 结合描述和含义可以进一步帮助翻译。下面的例子中就包含一个描述,其后紧跟着自定义 `id` : + The following example adds a meaning: +下面的例子添加了一个含义: + #### Define unique custom IDs +#### 定义唯一的自定义 ID + Be sure to define custom IDs that are unique. If you use the same ID for two different text elements, the extraction tool extracts only the first one, and Angular uses its translation in place of both original text elements. +一定要确保定义的自定义 ID 是唯一的。如果对两个不同的文本元素使用了相同的 ID,那么提取工具只会提取出第一个,而 Angular 会使用它的翻译来代替两个原始文本元素。 + For example, in the following code the same custom ID `myId` is defined for two different text elements: +例如,在下面的代码中,为两个不同的文本元素定义了相同的自定义 ID `myId`: + ```html

Hello

@@ -894,6 +1427,8 @@ For example, in the following code the same custom ID `myId` is defined for two The following shows the translation to French: +下面是它翻译成的法语: + ```xml Hello @@ -903,6 +1438,8 @@ The following shows the translation to French: Both elements now use the same translation (`Bonjour`) because they were defined with the same custom ID: +这两个元素现在都使用了相同的翻译( `Bonjour` ),这是因为它们是使用相同的自定义 ID 来定义的: + ```html

Bonjour

diff --git a/aio/content/guide/pipes.md b/aio/content/guide/pipes.md index f5047b2fa0..835b0c027c 100644 --- a/aio/content/guide/pipes.md +++ b/aio/content/guide/pipes.md @@ -1,50 +1,103 @@ # Transforming Data Using Pipes +# 用管道转换数据 + Use [pipes](guide/glossary#pipe "Definition of a pipe") to transform and format strings, currency amounts, dates, and other display data. Pipes are simple functions you can use in [template expressions](/guide/glossary#template-expression "Definition of template expression") to accept an input value and return a transformed value. For example, you would use a pipe to show a date as **April 15, 1988** rather than the raw string format. +[管道](guide/glossary#pipe "管道的定义")用来对字符串、货币金额、日期和其他显示数据进行转换和格式化。管道是一些简单的函数,可以在[模板表达式](/guide/glossary#template-expression "模板表达式的定义")中用来接受输入值并返回一个转换后的值。例如,你可以使用一个管道把日期显示为 **1988 年 4 月 15 日**,而不是其原始字符串格式。 +
For the sample app used in this topic, see the . + 本主题中使用的范例应用,参见。 +
Angular provides built-in pipes for typical data transformations, including transformations for internationalization (i18n), which use locale information to format data. The following are commonly used built-in pipes for data formatting: +Angular 为典型的数据转换提供了内置的管道,包括国际化的转换(i18n),它使用本地化信息来格式化数据。数据格式化常用的内置管道如下: + * [`DatePipe`](api/common/DatePipe): Formats a date value according to locale rules. + + [`DatePipe`](api/common/DatePipe):根据本地环境中的规则格式化日期值。 + * [`UpperCasePipe`](api/common/UpperCasePipe): Transforms text to all upper case. + + [`UpperCasePipe`](api/common/UpperCasePipe):把文本全部转换成大写。 + * [`LowerCasePipe`](api/common/LowerCasePipe): Transforms text to all lower case. + + [`LowerCasePipe`](api/common/LowerCasePipe) :把文本全部转换成小写。 + * [`CurrencyPipe`](api/common/CurrencyPipe): Transforms a number to a currency string, formatted according to locale rules. + + [`CurrencyPipe`](api/common/CurrencyPipe) :把数字转换成货币字符串,根据本地环境中的规则进行格式化。 + * [`DecimalPipe`](/api/common/DecimalPipe): Transforms a number into a string with a decimal point, formatted according to locale rules. + + [`DecimalPipe`](/api/common/DecimalPipe):把数字转换成带小数点的字符串,根据本地环境中的规则进行格式化。 + * [`PercentPipe`](api/common/PercentPipe): Transforms a number to a percentage string, formatted according to locale rules. + [`PercentPipe`](api/common/PercentPipe) :把数字转换成百分比字符串,根据本地环境中的规则进行格式化。 +
* For a complete list of built-in pipes, see the [pipes API documentation](/api/common#pipes "Pipes API reference summary"). + + 有关内置管道的完整列表,请参阅[管道 API 文档](/api/common#pipes "管道 API 参考总结") 。 + * To learn more about using pipes for internationalization (i18n) efforts, see [formatting data based on locale](/guide/i18n#i18n-pipes "Formatting data based on locale"). + 要了解有关使用管道进行国际化(i18n)工作的更多信息,请参阅[根据本地环境格式化数据](/guide/i18n#i18n-pipes "根据本地环境格式化数据") 。 +
You can also create pipes to encapsulate custom transformations and use your custom pipes in template expressions. +你还可以创建管道来封装自定义转换,并在模板表达式中使用自定义管道。 + ## Prerequisites +## 先决条件 + To use pipes you should have a basic understanding of the following: +要想使用管道,你应该对这些内容有基本的了解: + * [Typescript](guide/glossary#typescript "Definition of Typescript") and HTML5 programming + + [Typescript](guide/glossary#typescript "Typescript 的定义") 和 HTML5 编程 + * [Templates](guide/glossary#template "Definition of a template") in HTML with CSS styles + + 带有 CSS 样式的 HTML [模板](guide/glossary#template "模板的定义") + * [Components](guide/glossary#component "Definition of a component") + [组件](guide/glossary#component "组件的定义") + ## Using a pipe in a template +## 在模板中使用管道 + To apply a pipe, use the pipe operator (`|`) within a template expression as shown in the following code example, along with the *name* of the pipe, which is `date` for the built-in [`DatePipe`](api/common/DatePipe). The tabs in the example show the following: +要应用管道,请如下所示在模板表达式中使用管道操作符(`|`),紧接着是该管道的*名字*,对于内置的 [`DatePipe`](api/common/DatePipe) 它的名字是 `date` 。这个例子中的显示如下: + * `app.component.html` uses `date` in a separate template to display a birthday. + + `app.component.html` 在另一个单独的模板中使用 `date` 来显示生日。 + * `hero-birthday1.component.ts` uses the same pipe as part of an in-line template in a component that also sets the birthday value. + `hero-birthday1.component.ts` 使用相同的管道作为组件内嵌模板的一部分,同时该组件也会设置生日值。 + Date Format Toggle **Figure 1.** Clicking the button toggles the date format +**图 1.** 单击该按钮切换日期格式 +
For `date` pipe format options, see [DatePipe](api/common/DatePipe "DatePipe API Reference page"). +关于 `date` 管道的格式选项,参见 [DatePipe](api/common/DatePipe "DatePipe API 参考手册页面") 。 +
### Example: Applying two formats by chaining pipes +### 示例:通过串联管道应用两种格式 + You can chain pipes so that the output of one pipe becomes the input to the next. +你可以对管道进行串联,以便一个管道的输出成为下一个管道的输入。 + In the following example, chained pipes first apply a format to a date value, then convert the formatted date to uppercase characters. The first tab for the `src/app/app.component.html` template chains `DatePipe` and `UpperCasePipe` to display the birthday as **APR 15, 1988**. The second tab for the `src/app/app.component.html` template passes the `fullDate` parameter to `date` before chaining to `uppercase`, which produces **FRIDAY, APRIL 15, 1988**. +在下面的示例中,串联管道首先将格式应用于一个日期值,然后将格式化之后的日期转换为大写字符。 `src/app/app.component.html` 模板的第一个标签页把 `DatePipe` 和 `UpperCasePipe` 的串联起来,将其显示为 **APR 15, 1988**。`src/app/app.component.html` 模板的第二个标签页在串联 `uppercase` 之前,还把 `fullDate` 参数传递给了 `date`,将其显示为 **FRIDAY, APRIL 15, 1988**。 + * Include your pipe in the `declarations` field of the `NgModule` metadata in order for it to be available to a template. See the `app.module.ts` file in the example app (). For details, see [NgModules](guide/ngmodules "NgModules introduction"). + + 把你的管道包含在 `NgModule` 元数据的 `declarations` 字段中,以便它能用于模板。请查看示例应用中的 `app.module.ts` 文件()。有关详细信息,请参阅 [NgModules](guide/ngmodules "NgModules 简介") 。 + * Register your custom pipes. The [Angular CLI](cli "CLI Overview and Command Reference") [`ng generate pipe`](cli/generate#pipe "ng generate pipe in the CLI Command Reference") command registers the pipe automatically. + 注册自定义管道。[Angular CLI](cli "CLI 概述和命令参考") 的 [`ng generate pipe`](cli/generate#pipe "ng 在 CLI Command Reference 中生成管道") 命令会自动注册该管道。 + ### Using the PipeTransform interface +### 使用 PipeTransform 接口 + Implement the [`PipeTransform`](/api/core/PipeTransform "API reference for PipeTransform") interface in your custom pipe class to perform the transformation. +在自定义管道类中实现 [`PipeTransform`](/api/core/PipeTransform "PipeTransform 的 API 参考") 接口来执行转换。 + Angular invokes the `transform` method with the value of a binding as the first argument, and any parameters as the second argument in list form, and returns the transformed value. +Angular 调用 `transform` 方法,该方法使用绑定的值作为第一个参数,把其它任何参数都以列表的形式作为第二个参数,并返回转换后的值。 + ### Example: Transforming a value exponentially +### 示例:指数级转换 + In a game, you may want to implement a transformation that raises a value exponentially to increase a hero's power. For example, if the hero's score is 2, boosting the hero's power exponentially by 10 produces a score of 1024. You can use a custom pipe for this transformation. +在游戏中,你可能希望实现一种指数级转换,以指数级增加英雄的力量。例如,如果英雄的得分是 2,那么英雄的能量会指数级增长 10 次,最终得分为 1024。你可以使用自定义管道进行这种转换。 + The following code example shows two component definitions: +下列代码示例显示了两个组件定义: + * The `exponential-strength.pipe.ts` component defines a custom pipe named `exponentialStrength` with the `transform` method that performs the transformation. It defines an argument to the `transform` method (`exponent`) for a parameter passed to the pipe. + `exponential-strength.pipe.ts` 通过一个执行转换的 `transform` 方法定义了一个名为 `exponentialStrength` 的自定义管道。它为传递给管道的参数定义了 `transform` 方法的一个参数(`exponent`)。 + * The `power-booster.component.ts` component demonstrates how to use the pipe, specifying a value (`2`) and the exponent parameter (`10`). Figure 2 shows the output. + `power-booster.component.ts` 组件演示了如何使用该管道,指定了一个值( `2` )和一个 exponent 参数( `10` )。输出结果如图 2 所示。 + To examine the behavior the `exponentialStrength` pipe in the , change the value and optional exponent in the template. +要检查 `exponentialStrength` 管道的行为,请查看,并在模板中修改值和可选的指数参数。 + {@a change-detection} ## Detecting changes with data binding in pipes +## 通过管道中的数据绑定来检测变更 + You use [data binding](/guide/glossary#data-binding "Definition of data binding") with a pipe to display values and respond to user actions. If the data is a primitive input value, such as `String` or `Number`, or an object reference as input, such as `Date` or `Array`, Angular executes the pipe whenever it detects a change for the input value or reference. +你可以通过带有管道的[数据绑定](/guide/glossary#data-binding "数据绑定的定义")来显示值并响应用户操作。如果是原始类型的输入值,比如 `String` 或 `Number` ,或者是对象引用型的输入值,比如 `Date` 或 `Array` ,那么每当 Angular 检测到输入值或引用有变化时,就会执行该输入管道。 + For example, you could change the previous custom pipe example to use two-way data binding with `ngModel` to input the amount and boost factor, as shown in the following code example. +比如,你可以修改前面的自定义管道示例,通过 `ngModel` 的双向绑定来输入数量和提升因子,如下面的代码示例所示。 + The `exponentialStrength` pipe executes every time the user changes the "normal power" value or the "boost factor", as shown in Figure 3. +每当用户改变 “normal power” 值或 “boost factor” 时,就会执行 `exponentialStrength` 管道,如图 3 所示。 + **Figure 3.** Changing the amount and boost factor for the `exponentialStrength` pipe +**图 3.** 更改 `exponentialStrength` 管道的数值和提升因子 + Angular detects each change and immediately runs the pipe. This is fine for primitive input values. However, if you change something *inside* a composite object (such as the month of a date, an element of an array, or an object property), you need to understand how change detection works, and how to use an `impure` pipe. +Angular 会检测每次变更,并立即运行该管道。对于原始输入值,这很好。但是,如果要在复合对象中更改某些*内部值*(例如日期中的月份、数组中的元素或对象中的属性),就需要了解变更检测的工作原理,以及如何使用 `impure`(非纯)管道。 + ### How change detection works +### 变更检测的工作原理 + Angular looks for changes to data-bound values in a [change detection](guide/glossary#change-detection "Definition of change detection") process that runs after every DOM event: every keystroke, mouse move, timer tick, and server response. The following example, which doesn't use a pipe, demonstrates how Angular uses its default change detection strategy to monitor and update its display of every hero in the `heroes` array. The example tabs show the following: +Angular 会在每次 DOM 事件(每次按键、鼠标移动、计时器滴答和服务器响应)之后运行的[变更检测](guide/glossary#change-detection "变更检测的定义")过程中查找对数据绑定值的[更改](guide/glossary#change-detection "变更检测的定义")。下面这段不使用管道的例子演示了 Angular 如何利用默认的变更检测策略来监控和更新 `heroes` 数组中每个英雄的显示效果。示例显示如下: + * In the `flying-heroes.component.html (v1)` template, the `*ngFor` repeater displays the hero names. + + 在 `flying-heroes.component.html (v1)` 模板中, `*ngFor` 会重复显示英雄的名字。 + * Its companion component class `flying-heroes.component.ts (v1)` provides heroes, adds heroes into the array, and resets the array. + 与之相伴的组件类 `flying-heroes.component.ts (v1)` 提供了一些英雄,把这些英雄添加到数组中,并重置了该数组。 +
The change detector ignores changes to elements of an array, so the pipe doesn't run. +而变更检测器会忽略对数组元素的更改,所以管道不会运行。 + The reason Angular ignores the changed array element is that the *reference* to the array hasn't changed. Since the array is the same, Angular does not update the display. +Angular 忽略了被改变的数组元素的原因是对数组的*引用*没有改变。由于 Angular 认为该数组仍是相同的,所以不会更新其显示。 + One way to get the behavior you want is to change the object reference itself. You can replace the array with a new array containing the newly changed elements, and then input the new array to the pipe. In the above example, you can create an array with the new hero appended, and assign that to `heroes`. Angular detects the change in the array reference and executes the pipe. +获得所需行为的方法之一是更改对象引用本身。你可以用一个包含新更改过的元素的新数组替换该数组,然后把这个新数组作为输入传给管道。在上面的例子中,你可以创建一个附加了新英雄的数组,并把它赋值给 `heroes`。 Angular 检测到了这个数组引用的变化,并执行了该管道。 + To summarize, if you mutate the input array, the pure pipe doesn't execute. If you *replace* the input array, the pipe executes and the display is updated, as shown in Figure 4. +总结一下,如果修改了输入数组,纯管道就不会执行。如果*替换*了输入数组,就会执行该管道并更新显示,如图 4 所示。 + **Figure 4.** The `flyingHeroes` pipe filtering the display to flying heroes +**图 4.** `flyingHeroes` 管道把显示过滤为会飞的英雄 + The above example demonstrates changing a component's code to accommodate a pipe. +上面的例子演示了如何更改组件的代码来适应某个管道。 + To keep your component simpler and independent of HTML templates that use pipes, you can, as an alternative, use an *impure* pipe to detect changes within composite objects such as arrays, as described in the next section. +为了让你的组件更简单,独立于那些使用管道的 HTML,你可以用一个*不纯的*管道来检测复合对象(如数组)中的变化,如下一节所述。 + {@a impure-flying-heroes} ### Detecting impure changes within composite objects +### 检测复合对象中的非纯变更 + To execute a custom pipe after a change *within* a composite object, such as a change to an element of an array, you need to define your pipe as `impure` to detect impure changes. Angular executes an impure pipe every time it detects a change with every keystroke or mouse movement. +要在复合对象*内部*进行更改后执行自定义管道(例如更改数组元素),就需要把管道定义为 `impure` 以检测非纯的变更。每当按键或鼠标移动时,Angular 都会检测到一次变更,从而执行一个非纯管道。 +
While an impure pipe can be useful, be careful using one. A long-running impure pipe could dramatically slow down your app. +虽然非纯管道很实用,但要小心使用。长时间运行非纯管道可能会大大降低你的应用速度。 +
Make a pipe impure by setting its `pure` flag to `false`: +通过把 `pure` 标志设置为 `false` 来把管道设置成非纯的: + The following code shows the complete implementation of `FlyingHeroesImpurePipe`, which extends `FlyingHeroesPipe` to inherit its characteristics. The example shows that you don't have to change anything else—the only difference is setting the `pure` flag as `false` in the pipe metadata. +下面的代码显示了 `FlyingHeroesImpurePipe` 的完整实现,它扩展了 `FlyingHeroesPipe` 以继承其特性。这个例子表明你不需要修改其他任何东西 - 唯一的区别就是在管道元数据中把 `pure` 标志设置为 `false` 。 +
You can derive a `FlyingHeroesImpureComponent` from `FlyingHeroesComponent`. As shown in the code below, only the pipe in the template changes. +你可以从 `FlyingHeroesComponent` 派生一个 `FlyingHeroesImpureComponent`。如下面的代码所示,只有模板中的管道发生了变化。 +
To confirm that the display updates as the user adds heroes, see the . + 要想确认是否在用户添加英雄时更新了显示,请参阅。 +
{@a async-pipe} ## Unwrapping data from an observable +## 从一个可观察对象中解包数据 + [Observables](/guide/glossary#observable "Definition of observable") let you pass messages between parts of your application. Observables are recommended for event handling, asynchronous programming, and handling multiple values. Observables can deliver single or multiple values of any type, either synchronously (as a function delivers a value to its caller) or asynchronously on a schedule. +[可观察对象](/guide/glossary#observable "可观察对象的定义")能让你在应用的各个部分之间传递消息。建议在事件处理、异步编程以及处理多个值时使用这些可观察对象。可观察对象可以提供任意类型的单个或多个值,可以是同步的(作为一个函数为它的调用者提供一个值),也可以是异步的。 +
For details and examples of observables, see the [Observables Overview](/guide/observables#using-observables-to-pass-values "Using observables to pass values""). +有关可观察对象的详细信息和示例,请参阅[可观察对象概览](/guide/observables#using-observables-to-pass-values "使用可观察对象传递值“")。 +
Use the built-in [`AsyncPipe`](/api/common/AsyncPipe "API description of AsyncPipe") to accept an observable as input and subscribe to the input automatically. Without this pipe, your component code would have to subscribe to the observable to consume its values, extract the resolved values, expose them for binding, and unsubscribe when the observable is destroyed in order to prevent memory leaks. `AsyncPipe` is an impure pipe that saves boilerplate code in your component to maintain the subscription and keep delivering values from that observable as they arrive. +使用内置的 [`AsyncPipe`](/api/common/AsyncPipe "AsyncPipe 的 API 描述") 接受一个可观察对象作为输入,并自动订阅输入。如果没有这个管道,你的组件代码就必须订阅这个可观察对象来使用它的值,提取已解析的值、把它们公开进行绑定,并在销毁这段可观察对象时取消订阅,以防止内存泄漏。 `AsyncPipe` 是一个非纯管道,可以节省组件中的样板代码,以维护订阅,并在数据到达时持续从该可观察对象中提供值。 + The following code example binds an observable of message strings (`message$`) to a view with the `async` pipe. +下列代码示例使用 `async` 管道将带有消息字符串( `message$` )的可观察对象绑定到视图中。 + @@ -396,19 +600,32 @@ The following code example binds an observable of message strings ## Caching HTTP requests +## 缓存 HTTP 请求 + To [communicate with backend services using HTTP](/guide/http "Communicating with backend services using HTTP"), the `HttpClient` service uses observables and offers the `HTTPClient.get()` method to fetch data from a server. The aynchronous method sends an HTTP request, and returns an observable that emits the requested data for the response. +为了[使用 HTTP 与后端服务进行通信](/guide/http "使用 HTTP 与后端服务进行通信"),`HttpClient` 服务使用了可观察对象,并提供了 `HTTPClient.get()` 方法来从服务器获取数据。这个异步方法会发送一个 HTTP 请求,并返回一个可观察对象,它会发出请求到的响应数据。 + As shown in the previous section, you can use the impure `AsyncPipe` to accept an observable as input and subscribe to the input automatically. You can also create an impure pipe to make and cache an HTTP request. +如 `AsyncPipe` 所示,你可以使用非纯管道 `AsyncPipe` 接受一个可观察对象作为输入,并自动订阅输入。你也可以创建一个非纯管道来建立和缓存 HTTP 请求。 + Impure pipes are called whenever change detection runs for a component, which could be every few milliseconds for `CheckAlways`. To avoid performance problems, call the server only when the requested URL changes, as shown in the following example, and use the pipe to cache the server response. The tabs show the following: +每当组件运行变更检测时就会调用非纯管道,在 `CheckAlways` 策略下会每隔几毫秒运行一次。为避免出现性能问题,只有当请求的 URL 发生变化时才会调用该服务器(如下例所示),并使用该管道缓存服务器的响应。显示如下: + * The `fetch` pipe (`fetch-json.pipe.ts`). + + `fetch` 管道( `fetch-json.pipe.ts` )。 + * A harness component (`hero-list.component.ts`) for demonstrating the request, using a template that defines two bindings to the pipe requesting the heroes from the `heroes.json` file. The second binding chains the `fetch` pipe with the built-in `JsonPipe` to display the same hero data in JSON format. + 一个用于演示该请求的挽具组件(`hero-list.component.ts`),它使用一个模板,该模板定义了两个到该管道的绑定,该管道会向 `heroes.json` 文件请求英雄数组。第二个绑定把 `fetch` 管道与内置的 `JsonPipe` 串联起来,以 JSON 格式显示同一份英雄数据。 + Hero List **Figure 5.** The `fetch` and `fetch-json` pipes displaying the heroes +**图 5.** `fetch` 和 `fetch-json` 管道显示了这些英雄。 +
The built-in [JsonPipe](api/common/JsonPipe "API description for JsonPipe") provides a way to diagnose a mysteriously failing data binding or to inspect an object for future binding. +内置的 [JsonPipe](api/common/JsonPipe "JsonPipe 的 API 描述") 提供了一种方法来诊断一个离奇失败的数据绑定,或用来检查一个对象是否能用于将来的绑定。 +