From 68392d3fb071a724ee962f9c25480718f99b4b68 Mon Sep 17 00:00:00 2001 From: Rex Ye Date: Tue, 17 May 2016 15:42:22 +0100 Subject: [PATCH] review of forms.jade in guide. --- public/docs/ts/latest/guide/forms.jade | 152 +++++++++++++++++++++---- 1 file changed, 128 insertions(+), 24 deletions(-) diff --git a/public/docs/ts/latest/guide/forms.jade b/public/docs/ts/latest/guide/forms.jade index af05c5bbfa..5f6580bed3 100644 --- a/public/docs/ts/latest/guide/forms.jade +++ b/public/docs/ts/latest/guide/forms.jade @@ -13,7 +13,7 @@ include ../_util-fns user efficiently and effectively through the workflow behind the form. 不管什么样的Web开发者,都能使用正确的标签“捏”出一个HTML。 - 但要想做出一个优秀的表单,让它具有贴心的数据输入体验,以指导用户明晰、高效的走通表单背后的工作流,这个挑战就大多了。 + 但要想做出一个优秀的表单,让它具有贴心的数据输入体验,以指导用户明晰、高效的通过表单完成背后的工作流程,这个挑战就大多了。 *That* takes design skills that are, to be frank, well out of scope for this chapter. @@ -28,24 +28,30 @@ include ../_util-fns We will build a simple form from scratch, one step at a time. Along the way we'll learn - 我们将构建一个简单的表单,我们把它简化到只需要一次一步。通过这种方式,我们将学到: + 我们将从零构建一个简单的表单,把它简化到一次一步。通过这种方式,我们将学到: - to build an Angular form with a component and template + - 使用组件和模板构建一个Angular表单 - two-way data binding with `[(ngModel)]` syntax for reading and writing values to input controls - - 使用`[(ngModel)]`语法实现双向数据绑定,以便从输入控件中读取和写入值 + + - 使用`[(ngModel)]`语法实现双向数据绑定,以便输入控件的值读取和写入 - using `ngControl` to track the change state and validity of form controls + - 使用`ngControl`来跟踪变更状态并对表单控件做验证 - the special CSS classes that `ngControl` adds to form controls and how we can use them to provide strong visual feedback + - `ngControl`添加到表单控件上的那些特殊的CSS类,以及我们该如何使用它们来提供强烈的视觉反馈 - displaying validation errors to users and enable/disable form controls + - 向用户显示有效性验证的错误提示,以及禁用/使能表单控件 - sharing information among controls with template reference variables + - 通过模板引用变量,在控件之间共享信息 [Live Example](/resources/live-examples/forms/ts/plnkr.html) @@ -54,17 +60,20 @@ include ../_util-fns .l-main-section :marked ## Template-Driven Forms + ## 模板驱动的表单 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 That's not the only way to create a form but it's the way we'll cover in this chapter. 这不是创建表单的唯一方式,但它是我们将在本章中使用的方式。 + :marked We can build almost any form we need with an Angular template — login forms, contact forms ... pretty much any business forms. We can lay out the controls creatively, bind them to data, specify validation rules and display validation errors, @@ -89,7 +98,7 @@ 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. @@ -118,40 +127,60 @@ figure.image-display 我们将按照一系列很小的步骤来构建此表单: 1. Create the `Hero` model class + 1. 创建`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`双向数据绑定语法把数据属性绑定到每个表单输入控件 + 1. Add the **ngControl** directive to each form input control + 1. 往每个表单输入控件上添加**ngControl**指令 + 1. Add custom CSS to provide visual feedback - 1. 添加自定义CSS来显示视觉反馈 + + 1. 添加自定义CSS来提供视觉反馈 + 1. Show and hide validation error messages + 1. 显示和隐藏有效性验证的错误信息 + 1. Handle form submission with **ngSubmit** + 1. 使用**ngSubmit**处理表单提交 + 1. Disable the form’s submit button until the form is valid + 1. 禁用此表单的提交按钮,直到表单变为有效的 :marked ## Setup + ## 起步 + Create a new project folder (`angular2-forms`) and follow the steps in the [QuickStart](../quickstart.html). - 创建一个新的项目文件夹(`angular2-forms`),并且遵循[QuickStart](../quickstart.html)中的步骤进行初始化。 + 创建一个新的项目文件夹(`angular2-forms`),并且完成[快速开始](../quickstart.html)中的步骤。 include ../_quickstart_repo :marked ## Create the Hero Model Class + ## 创建一个Hero模型类 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. @@ -193,6 +222,7 @@ code-example(format=""). .l-main-section :marked ## Create a Form component + ## 创建一个表单组件 An Angular form has two parts: an HTML-based template and a code-based Component to handle data and user interactions. @@ -219,25 +249,30 @@ code-example(format=""). 要理解这个组件,只会用到前面章节中已经学过的那些概念: 1. We import the `Component` decorator from the Angular library as we usually do. + 1. 像往常一样,我们从Angular库中导入`Component`装饰器。 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"表示我们将把此表单扔进父模板中的一个``标签中。 1. The `templateUrl` property points to a separate file for template HTML called `hero-form.component.html`. + 1. `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),以绑定到父组件上。 - 我们现在所关注的这些变更点,即使将来真的发生了,也不会影响到我们的表单。 + 我们目前不关心这些,因为将来这些变化不会影响到我们的表单。 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形式。 它会帮我们看清开发过程中发生的事,等最后做清理时我们会丢弃它。 @@ -251,7 +286,7 @@ code-example(format=""). write (or read) large stretches of HTML and few editors are much help with files that have a mix of HTML and code. We also like short files with a clear and obvious purpose like this one. - 没有什么回答在所有场合都是“正确”的。当行内模板足够短的时候,我们喜欢用它。 + 没有什么答案在所有场合都总是“正确”的。当行内联模板足够短的时候,我们喜欢用它。 但大多数的表单模板都不短。普遍来讲,TypeScript和JavaScript文件不会是写大型HTML的好地方(也不好读)。 而且没有几个编辑器能对混写的HTML和代码提供足够的帮助。 我们还是喜欢写成像这个一样清晰明确的短文件。 @@ -266,6 +301,7 @@ code-example(format=""). .l-main-section :marked ## Revise the *app.component.ts* + ## 修改*app.component.ts*文件 `app.component.ts` is the application's root component. It will host our new `HeroFormComponent`. @@ -274,7 +310,7 @@ code-example(format=""). Replace the contents of the "QuickStart" version with the following: - 把"QuickStart"版的内容替换成下列代码: + 把"快速开始"的版本内容替换成下列代码: +makeExample('forms/ts/app/app.component.ts', null, 'app/app.component.ts') :marked @@ -285,18 +321,22 @@ code-example(format=""). 只有三处修改: 1. We import the new `HeroFormComponent`. + 1. 导入了新的`HeroFormComponent`组件。 1. The `template` is simply the new element tag identified by the component's `selector` property. + 1. 直接把`template`的内容改成`HeroFormComponent`的`selector`属性中指定的新元素标签。 1. The `directives` array tells Angular that our template depends upon the `HeroFormComponent` which is itself a Directive (as are all Components). + 1. `directives`数组告诉Angular,我们的模板依赖于`HeroFormComponent`组件,它本身也是一个指令(所有组件都是指令)。 .l-main-section :marked ## Create an initial HTML Form Template + ## 创建一个初始的HTML表单模板 Create a new template file called `hero-form.component.html` and give it the following definition: @@ -309,7 +349,7 @@ 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. @@ -335,7 +375,9 @@ code-example(format=""). .callout.is-important header Angular Forms Do Not Require A Style Library + 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 @@ -350,17 +392,21 @@ code-example(format=""). ol li Open a terminal window in the application root folder and enter the command: + 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=".") :marked .l-main-section :marked ## Add Powers with ***ngFor** + ## 用***ngFor***添加超能力 + Our hero may choose one super power from a fixed list of Agency-approved powers. We maintain that list internally (in `HeroFormComponent`). @@ -377,6 +423,7 @@ ol Add the following HTML *immediately below* the *Alter Ego* group. 在*Alter Ego*的紧下方添加如下HTML: + +makeExample('forms/ts/app/hero-form.component.html', 'powers', 'app/hero-form.component.html (节选)')(format=".") :marked @@ -384,14 +431,16 @@ ol The `p` template input variable is a different power in each iteration; we display its name using the interpolation syntax with the double-curly-braces. - 我们为列表中的每一项超能力重复渲染出`