From 2b3c8e5a64a5cb494cfeeac142b9ca6cb4c9b4da Mon Sep 17 00:00:00 2001 From: Yang Lin Date: Sat, 26 Nov 2016 03:16:06 +0800 Subject: [PATCH] Polish forms.jade --- public/docs/ts/latest/guide/forms.jade | 439 +++++++++++++------------ public/resources/css/_translate.scss | 5 +- 2 files changed, 229 insertions(+), 215 deletions(-) diff --git a/public/docs/ts/latest/guide/forms.jade b/public/docs/ts/latest/guide/forms.jade index 67054a4df9..1e220a584e 100644 --- a/public/docs/ts/latest/guide/forms.jade +++ b/public/docs/ts/latest/guide/forms.jade @@ -5,15 +5,15 @@ include ../_util-fns schedule a meeting and perform countless other data entry tasks. Forms are the mainstay of business applications. - 我们全都用过表单来执行登录、求助、下单、预订机票、发起会议,以及不计其数的其它数据录入任务。 - 表单是商业应用的主体。 + 表单是商业应用的支柱,我们用它来执行登录、求助、下单、预订机票、安排会议,以及不计其数的其它数据录入任务。 Any seasoned web developer can slap together an HTML form with all the right tags. It's more challenging to create a cohesive data entry experience that guides the user efficiently and effectively through the workflow behind the form. - 不管什么样的Web开发者,都能使用适当的标签“捏”出一个HTML。 - 但是,要想做出一个优秀的表单,让它具有贴心的数据输入体验,以指导用户明晰、高效的通过表单完成背后的工作流程,这个挑战就大多了。 + 任何经验丰富的Web开发人员都能使用适当的标签拼凑出一个HTML表单。 + 但是,要想做出一个具有贴心的数据输入体验的表单, + 引导用户明晰、高效地完成表单背后的工作流程,这个挑战就大多了。 *That* takes design skills that are, to be frank, well out of scope for this chapter. @@ -40,7 +40,7 @@ include ../_util-fns - track the change state and validity of form controls using `ngModel` in combination with a form - - 结合表单来使用`ngModel`,能让我们跟踪状态的变化并对表单控件做验证 + - 结合表单来使用`ngModel`,我们可以跟踪表单控件的状态变化和有效性 - provide strong visual feedback using special CSS classes that track the state of the controls @@ -48,11 +48,11 @@ include ../_util-fns - display validation errors to users and enable/disable form controls - - 向用户显示有效性验证的错误提示,以及禁用/启用表单控件 + - 向用户显示有效性验证的错误提示,以及启用/禁用表单控件 - use [template reference variables](./template-syntax.html#ref-vars) for sharing information among HTML elements - - 通过模板引用变量,在控件之间共享信息 + - 使用[模板引用变量](./template-syntax.html#ref-vars),在HTML元素之间共享信息 Run the . @@ -67,7 +67,7 @@ include ../_util-fns Many of us will build forms by writing templates in the Angular [template syntax](./template-syntax.html) with the form-specific directives and techniques described in this chapter. - 我们大多数都可以使用表单特有的指令和本章所描述的技术,在模板中按照Angular[模板语法](./template-syntax.html)来构建表单。 + 通常,我们用Angular[模板语法](./template-syntax.html)编写模板,结合本章所描述的表单专用指令和技术来构建表单。 .l-sub-section :marked @@ -80,13 +80,14 @@ include ../_util-fns We can lay out the controls creatively, bind them to data, specify validation rules and display validation errors, conditionally enable or disable specific controls, trigger built-in visual feedback, and much more. - 利用Angular模板,我们可以构建几乎所有表单 —— 登录表单、联系人表单…… 大量的各种商务表单。 - 我们可以创造性的摆放各种控件、把它们绑定到数据、指定校验规则、显示校验错误、有条件的禁用/启用特定的控件、触发内置的视觉反馈等等,不胜枚举。 + 利用Angular模板,我们可以构建几乎所有表单 —— 登录表单、联系人表单…… 以及任何的商务表单。 + 我们可以创造性的摆放各种控件、把它们绑定到数据、指定校验规则、显示校验错误、有条件的禁用或 + 启用特定的控件、触发内置的视觉反馈等等,不胜枚举。 It will be pretty easy because Angular handles many of the repetitive, boiler plate tasks we'd otherwise wrestle with ourselves. - 它的确很简单,这是因为Angular帮我们处理了大多数重复、单调的任务,这让我们可以不必亲自操刀、身陷其中。 + 它用起来很简单,这是因为Angular帮我们处理了大多数重复、单调的任务,这让我们可以不必亲自操刀、身陷其中。 We'll discuss and learn to build the following template-driven form: @@ -99,11 +100,11 @@ figure.image-display Here at the *Hero Employment Agency* we use this form to maintain personal information about the heroes in our stable. Every hero needs a job. It's our company mission to match the right hero with the right crisis! - 这里是*英雄管理局*,我们使用这个表单来维护候选英雄们的个人信息。每个英雄都需要一份工作。我们公司的任务就是让适当的英雄去解决它/她所擅长应对的危机! + 这里是*英雄职业介绍所*,我们使用这个表单来维护候选英雄们的个人信息。每个英雄都需要一份工作。我们公司的任务就是让适当的英雄去解决它/她所擅长应对的危机! Two of the three fields on this form are required. Required fields have a green bar on the left to make them easy to spot. - 这个表单中的三个字段都是必填的。这些必填的字段在左侧会有一个绿色的竖条,让它们更容易看出来。 + 表单中的三个字段,其中两个是必填的。必填的字段在左侧会有一个绿色的竖条,方便用户分辨哪些是必填项。 If we delete the hero name, the form displays a validation error in an attention grabbing style: @@ -129,39 +130,39 @@ figure.image-display 1. Create the `Hero` model class - 1. 创建`Hero`模型类 + 创建`Hero`模型类 1. Create the component that controls the form - 1. 创建控制此表单的组件 + 创建控制此表单的组件 1. Create a template with the initial form layout - 1. 创建具有初始表单布局的模板 + 创建具有初始表单布局的模板 1. Bind data properties to each form input control with the `ngModel` two-way data binding syntax - 1. 使用`ngModel`双向数据绑定语法把数据属性绑定到每个表单输入控件 + 使用`ngModel`双向数据绑定语法把数据属性绑定到每个表单输入控件 1. Add the `name` attribute to each form input control - 1. 往每个表单输入控件上添加`name`属性(Attribute) + 往每个表单输入控件上添加`name`属性 (attribute) 1. Add custom CSS to provide visual feedback - 1. 添加自定义CSS来提供视觉反馈 + 添加自定义 CSS 来提供视觉反馈 1. Show and hide validation error messages - 1. 显示和隐藏有效性验证的错误信息 + 显示和隐藏有效性验证的错误信息 1. Handle form submission with **ngSubmit** - 1. 使用**ngSubmit**处理表单提交 + 使用**ngSubmit**处理表单提交 1. Disable the form’s submit button until the form is valid - 1. 禁用此表单的提交按钮,直到表单变为有效 + 禁用此表单的提交按钮,直到表单变为有效 :marked ## Setup @@ -170,7 +171,7 @@ figure.image-display Create a new project folder (`angular-forms`) and follow the steps in the [QuickStart](../quickstart.html). - 创建一个新的项目文件夹(`angular-forms`),并且完成[“快速起步”](../quickstart.html)中的步骤。 + 创建一个新的项目文件夹 (`angular-forms`),并且完成[“快速起步”](../quickstart.html)中的步骤。 include ../_quickstart_repo :marked @@ -181,15 +182,15 @@ include ../_quickstart_repo As users enter form data, we capture their changes and update an instance of a model. We can't layout the form until we know what the model looks like. - 当用户输入表单数据时,我们要捕获它们的变化,并更新到模型的一个实例中。 - 除非我们知道模型里有什么,否则无法设计表单。 + 当用户输入表单数据时,需要捕获它们的变化,并更新到模型的一个实例中。 + 除非知道模型里有什么,否则无法设计表单的布局。 A model can be as simple as a "property bag" that holds facts about a thing of application importance. That describes well our `Hero` class with its three required fields (`id`, `name`, `power`) and one optional field (`alterEgo`). 最简单的模型就是一个“属性包”,用来存放应用中一件事物的事实。 - 这里我们使用三个必备字段(`id`、`name`、`power`),和一个可选字段(`alterEgo`,译注:中文含义:第二人格,比如X战警中的Jean/黑凤凰)。 + 这里使用三个必备字段 (`id`、`name`、`power`),和一个可选字段 (`alterEgo`,译注:中文含义:第二人格,比如X战警中的Jean/黑凤凰)。 Create a new file in the app folder called `hero.ts` and give it the following class definition: @@ -205,11 +206,11 @@ include ../_quickstart_repo The TypeScript compiler generates a public field for each `public` constructor parameter and assigns the parameter’s value to that field automatically when we create new heroes. - TypeScript编译器为构造函数中每个标为`public`的参数创建一个公有字段,并在创建新的英雄实例时,把参数值自动赋给这些公有字段。 + TypeScript 编译器为每个`public`构造函数参数生成一个公共字段,在创建新的英雄实例时,自动把参数值赋给这些公共字段。 The `alterEgo` is optional and the constructor lets us omit it; note the (?) in `alterEgo?`. - `alterEgo`是可选的,构造函数允许我们省略它,注意`alterEgo?`中的问号(?)。 + `alterEgo`是可选的,构造函数允许我们省略它,注意`alterEgo?`中的问号 (?)。 We can create a new hero like this: @@ -229,7 +230,7 @@ code-example(format=""). An Angular form has two parts: an HTML-based template and a code-based Component to handle data and user interactions. - 每个Angular表单分为两部分:一个基于HTML的模板,和一个基于代码的组件,它用来处理数据和用户交互。 + 每个Angular表单分为两部分:基于HTML的模板和基于代码的组件。组件用来处理数据和用户交互。 We begin with the Component because it states, in brief, what the Hero editor can do. @@ -244,52 +245,52 @@ code-example(format=""). :marked There’s nothing special about this component, nothing form-specific, nothing to distinguish it from any component we've written before. - 本组件没有什么特别的地方:没有表单相关的东西,也没有任何地方能把它和我们以前写过的那些组件区分开。 + 本组件没有什么特别的地方,没有表单相关的东西,与之前写过的组件没什么不同。 Understanding this component requires only the Angular concepts we’ve learned in previous chapters - 只需要用到前面章节中已经学过的那些概念,就可以完全理解这个组件: + 只需要前面章节中学过的概念,就可以完全理解这个组件: 1. We import the `Component` decorator from the Angular library as we usually do. - 1. 像往常一样,我们从Angular库中导入`Component`装饰器。 + 像往常一样,我们从 Angular 库中导入`Component`装饰器。 1. We import the `Hero` model we just created. - 1. 导入刚刚创建的`Hero`模型 + 导入刚刚创建的`Hero`模型。 1. The `@Component` selector value of "hero-form" means we can drop this form in a parent template with a `` tag. - 1. `@Component`选择器"hero-form"表示我们可以通过一个``标签,把此表单扔进父模板中。 + `@Component`选择器"hero-form"表示可以用``标签把这个表单放进父模板。 1. The `moduleId: module.id` property sets the base for module-relative loading of the `templateUrl`. - 1. `moduleId: module.id`属性设置了以相对于模块的路径加载`templateUrl`时使用的基地址。 + `moduleId: module.id`属性设置了基地址,用于从相对模块路径加载`templateUrl`。 1. The `templateUrl` property points to a separate file for the template HTML called `hero-form.component.html`. - 1. `templateUrl`属性指向一个独立的HTML模板文件,名叫`hero-form.component.html`。 + `templateUrl`属性指向一个独立的 HTML 模板文件,名叫`hero-form.component.html`。 1. We defined dummy data for `model` and `powers` as befits a demo. Down the road, we can inject a data service to get and save real data or perhaps expose these properties as [inputs and outputs](./template-syntax.html#inputs-outputs) for binding to a parent component. None of this concerns us now and these future changes won't affect our form. - 1. 我们为`model`和`powers`定义了供演示用的假数据。 - 接下来,我们可以注入一个用于获取和保存真实数据的服务, - 或者把这些属性暴露为[输入与输出属性](./template-syntax.html#inputs-outputs),以绑定到父组件上。 - 我们目前不关心这些,因为将来这些变化不会影响到我们的表单。 + 为`model`和`powers`定义了供演示用的假数据。 + 将来,可以注入一个服务来获取和保存真实数据, + 或者暴露这些属性为[输入与输出属性](./template-syntax.html#inputs-outputs),绑定到父组件上。 + 我们目前不关心这些,因为这些未来的变化不会影响到我们的表单。 1. We threw in a `diagnostic` property at the end to return a JSON representation of our model. It'll help us see what we're doing during our development; we've left ourselves a cleanup note to discard it later. - 1. 我们在最后增加一个`diagnostic`属性,它返回这个模型的JSON形式。 - 它会帮我们看清开发过程中发生的事,等最后做清理时我们会丢弃它。 + 我们在最后增加一个`diagnostic`属性,它返回这个模型的JSON形式。 + 在开发过程中,它用于调试,最后清理时我们会丢弃它。 Why don't we write the template inline in the component file as we often do elsewhere in the Developer Guide? - 这次我们为什么不像在开发指南中的其它地方那样,以内联的方式把模板放到组件文件呢? + 这次我们为什么不像在开发指南其它地方那样,以内联的方式把模板写在组件文件中呢? There is no “right” answer for all occasions. We like inline templates when they are short. Most form templates won't be short. TypeScript and JavaScript files generally aren't the best place to @@ -297,32 +298,32 @@ code-example(format=""). We also like short files with a clear and obvious purpose like this one. 没有什么答案在所有场合都总是“正确”的。当内联模板足够短的时候,我们更喜欢用它。 - 但大多数的表单模板都不短。普遍来讲,TypeScript和JavaScript文件不是写大型HTML的好地方(也不好读)。 - 而且没有几个编辑器能对混写的HTML和代码提供足够的帮助。 - 我们还是喜欢写成像这个一样清晰明确的短文件。 + 但大多数的表单模板都不短。通常,TypeScript 和 JavaScript 文件不是写(读)大型 HTML 的好地方, + 而且没有几个编辑器能对混写的 HTML 和代码提供足够的帮助。 + 我们还是喜欢清晰明确的短文件,像这个一样。 We made a good choice to put the HTML template elsewhere. We'll write that template in a moment. Before we do, we'll take a step back and revise the `app.module.ts` and `app.component.ts` to make use of our new `HeroFormComponent`. - 把HTML模板放在别处是一个好的选择。 - 我们一会儿就去写那个模板。在这之前,我们先回来修改`app.module.ts`和`app.component.ts`文件,来让它用上我们新的`HeroFormComponent`组件。 + 把 HTML 模板放在其它地方是个不错的选择。等会儿就去写那个模板。 + 在这之前,先回来修改`app.module.ts`和`app.component.ts`文件,用上新写的`HeroFormComponent`组件。 .l-main-section :marked ## Revise the *app.module.ts* - ## 修改 *app.module.ts** + ## 修改 *app.module.ts* `app.module.ts` defines the application's root module. In it we identify the external modules we'll use in our application and declare the components that belong to this module, such as our `HeroFormComponent`. - `app.module.ts`定义了应用的根模块。在那里,我们指出了即将用到的外部模块,并且声明了属于本模块中的组件,比如`HeroFormComponent`。 + `app.module.ts`定义了应用的根模块。其中标识即将用到的外部模块,以及声明属于本模块中的组件,如`HeroFormComponent`。 Because template-driven forms are in their own module, we need to add the `FormsModule` to the array of `imports` for our application module before we can use forms. - 因为模板驱动的表单有它们自己的模块,所以我们得把`FormsModule`添加到本应用的`imports`数组中,这样我们才能使用表单。 + 因为模板驱动的表单位于它们自己的模块,所以在使用表单之前,需要将`FormsModule`添加到应用模块的`imports`数组中。 Replace the contents of the "QuickStart" version with the following: @@ -338,35 +339,35 @@ code-example(format=""). 1. We import `FormsModule` and our new `HeroFormComponent`. - 1. 我们导入了`FormsModule`以及新组件`HeroFormComponent`。 + 导入`FormsModule`和新组件`HeroFormComponent`。 1. We add the `FormsModule` to the list of `imports` defined in the `ngModule` decorator. This gives our application access to all of the template-driven forms features, including `ngModel`. - 1. 我们把`FormsModule`添加到`ngModule`装饰器的`imports`列表中。这会让我们的应用能使用模板驱动表单的所有特性,包括`ngModel`。 + 把`FormsModule`添加到`ngModule`装饰器的`imports`列表中。使应用能访问模板驱动表单的所有特性,包括`ngModel`。 1. We add the `HeroFormComponent` to the list of `declarations` defined in the `ngModule` decorator. This makes the `HeroFormComponent` component visible throughout this module. - 1. 我们把`HeroFormComponent`添加到`ngModule`装饰器的`declarations`列表中。这让`HeroFormComponent`组件在本模块中随处都可访问。 + 把`HeroFormComponent`添加到`ngModule`装饰器的`declarations`列表中。使`HeroFormComponent`组件在整个模块中可见。 .alert.is-important :marked If a component, directive, or pipe belongs to a module in the `imports` array, ​_DON'T_​ declare it in the `declarations` array. If you wrote it and it should belong to this module, ​_DO_​ declare it in the `declarations` array. - 如果一个组件、指令或管道出现在模块的`imports`数组中,就说明它是外来模块,_不要_再到`declarations`数组中声明它们。 - 如果你自己写的它,并且它属于当前模块,_就要_把它声明在`declarations`数组中。 + 如果一个组件、指令或管道出现在模块的`imports`数组中,_不要_把它声明在`declarations`数组中。 + 如果它是你自己写的,并且属于当前模块,_就要_把它声明在`declarations`数组中。 .l-main-section :marked ## Revise the *app.component.ts* - ## 修改*app.component.ts*文件 + ## 修改 *app.component.ts* `app.component.ts` is the application's root component. It will host our new `HeroFormComponent`. - `app.component.ts`是本应用的根组件,我们的`HeroFormComponent`将被放在其中。 + `app.component.ts`是本应用的根组件,`HeroFormComponent`将被放在其中。 Replace the contents of the "QuickStart" version with the following: @@ -383,18 +384,17 @@ code-example(format=""). 1. The `template` is simply the new element tag identified by the component's `selector` property. This will display the hero form when the application component is loaded. - 1. 直接把`template`的内容改成`HeroFormComponent`的`selector`属性中指定的新元素标签。 - 于是当应用组件被加载时,将显示这个英雄表单。 + 1. `template`中只有新元素标签,即组件的`selector`属性。当应用组件被加载时,将显示这个英雄表单。 .l-main-section :marked ## Create an initial HTML Form Template - ## 创建一个初始HTML表单模板 + ## 创建一个初始 HTML 表单模板 Create a new template file called `hero-form.component.html` and give it the following definition: - 创建一个新的模板文件,命名为`hero-form.component.html`,并且填写如下内容: + 新建模板文件,命名为`hero-form.component.html`,并且填写如下内容: +makeExample('forms/ts/app/hero-form.component.html', 'start', 'app/hero-form.component.html') @@ -402,41 +402,42 @@ code-example(format=""). That is plain old HTML 5. We're presenting two of the `Hero` fields, `name` and `alterEgo`, and opening them up for user input in input boxes. - 这只是一段普通的旧式HTML 5代码。这里出现了两个`Hero`字段,`name`和`alterEgo`,让用户可以在输入框中输入,修改它们。 + 这只是一段普通的旧式 HTML 5 代码。这里有两个`Hero`字段,`name`和`alterEgo`,供用户输入。 The *Name* `` control has the HTML5 `required` attribute; the *Alter Ego* `` control does not because `alterEgo` is optional. - *Name*``控件具有HTML5的`required`属性;但 *Alter Ego* ``控件没有,因为`alterEgo`字段是可选的。 + *Name* ``控件具有 HTML5 的`required`属性;但 *Alter Ego* ``控件没有,因为`alterEgo`字段是可选的。 We've got a *Submit* button at the bottom with some classes on it for styling. - 我们在底部有一个*Submit*按钮,它有一些用来添加样式的CSS类。 + 我们在底部有一个 *Submit* 按钮,它有一些 CSS 样式类。 **We are not using Angular yet**. There are no bindings. No extra directives. Just layout. - **我们还没有用到Angular**。没有绑定。没有额外的指令。只做了个布局。 + **我们还没有用到Angular**。没有绑定,没有额外的指令,只有布局。 The `container`, `form-group`, `form-control`, and `btn` classes come from [Twitter Bootstrap](http://getbootstrap.com/css/). Purely cosmetic. We're using Bootstrap to gussy up our form. Hey, what's a form without a little style! - `container`、`form-group`、`form-control`和`btn`类来自[Twitter Bootstrap](http://getbootstrap.com/css/)。纯粹是装饰。 - 我们使用Bootstrap来打扮我们的表单。 + `container`、`form-group`、`form-control`和`btn`类来自 [Twitter Bootstrap](http://getbootstrap.com/css/)。纯粹是装饰。 + 我们使用 Bootstrap 来美化我们的表单。 嘿,一点样式都没有的表单算个啥! .callout.is-important header Angular Forms Do Not Require A Style Library - header Angular表单不需要任何样式库 + header Angular 表单不需要任何样式库 :marked Angular makes no use of the `container`, `form-group`, `form-control`, and `btn` classes or the styles of any external library. Angular apps can use any CSS library ... or none at all. - Angular不需要`container`、`form-group`、`form-control`和`btn`类,或者来自任何第三方库的任何样式,Angular应用可以使用任何CSS库 …… 或者啥都不用。 + Angular 不需要`container`、`form-group`、`form-control`和`btn`类, + 或者外部库的任何样式。Angular 应用可以使用任何 CSS 库…… ,或者啥都不用。 :marked Let's add the stylesheet. @@ -444,38 +445,43 @@ code-example(format=""). 我们来添加样式表。 ol - li Open a terminal window in the application root folder and enter the command: + li + p Open a terminal window in the application root folder and enter the command: + + p 在应用的根目录下打开一个终端窗口,敲如下命令: - li 在应用的根目录下打开一个终端窗口,敲如下命令: code-example(language="html" escape="html"). npm install bootstrap --save - li Open index.html and add the following link to the <head>. - li 打开index.html文件并且把下列链接添加到<head>中。 - +makeExample('forms/ts/index.html', 'bootstrap')(format=".") + li + p Open index.html and add the following link to the <head>. + + p 打开index.html文件并且把下列链接添加到<head>中。 + + +makeExample('forms/ts/index.html', 'bootstrap')(format=".") :marked .l-main-section :marked ## Add Powers with ***ngFor** - ## 用***ngFor***添加超能力 + ## 用 ***ngFor*** 添加超能力 Our hero may choose one super power from a fixed list of Agency-approved powers. We maintain that list internally (in `HeroFormComponent`). - 我们的英雄可以从由英雄管理局认证过的固定列表中选择一项超能力。 - 我们先在`HeroFormComponent`中内部维护这个列表。 + 英雄可以从由认证过的固定列表中选择一项超能力。 + 我们在`HeroFormComponent`中内部维护这个列表。 We'll add a `select` to our form and bind the options to the `powers` list using `ngFor`, a technique we might have seen before in the [Displaying Data](./displaying-data.html) chapter. - 我们将添加一个`select`到表单中,并且用`ngFor`把`powers`列表绑定到`option`中。 + 在表单中添加`select`,用`ngFor`把`powers`列表绑定到列表选项。 前面我们应该在[显示数据](./displaying-data.html)一章中见过`ngFor`。 Add the following HTML *immediately below* the *Alter Ego* group. - 在*Alter Ego*的紧下方添加如下HTML: + 在 *Alter Ego* 的紧下方添加如下 HTML: +makeExample('forms/ts/app/hero-form.component.html', 'powers', 'app/hero-form.component.html (excerpt)')(format=".") :marked @@ -484,14 +490,14 @@ ol we display its name using the interpolation syntax with the double-curly-braces. 我们为列表中的每一项超能力渲染出一个`