Tiven Wang
Wang Tiven March 22, 2018
425 favorite favorites
bookmark bookmark
share share

先来看一下一个 Component 响应用户输入的方式, Angular event bindings 方式为 (事件名称)="表达式"<button (click)="onClickMe()">Click me!</button>

在执行的表达式里还可以传入 $event 对象,他代表原始的 DOM 事件对象。我们不推荐这种使用方式,这会打破解耦 Template (用户界面)和 Component (应用程序如何处理用户数据) 的原则,增加他们之间的耦合性。

那么可以换一种方式,使用 template reference variable ,例如 <input #box (keyup)="onKey(box.value)">
进一步 Angular 的 pseudo-event 精细化过滤事件类型以减少计算量,如当点击 enter 时才触发 <input #box (keyup.enter)="onEnter(box.value)">

Form 是应用程序承担用户输入信息的主要形式,你可以用 Form 做各种比如登录,提交帮助请求,提交一个订单,预订机票,约个会议等大量的数据录入任务。那么 Form 界面的用户体验就尤为重要。

Template-driven forms

先来看一下如何通过 Template 驱动的方式创建 Form 。先生成一个 Model class Account
ng generate class Account

export class Account {
  constructor(
    public username: string,
    public password: string
  ){}  
}

然后就可以在 Component class 里创建一个类型为 Account 的属性,代表下面要讲的 Form 输入信息的模型变量。

...
export class AppComponent {
  account: Account;
  ...
}

在使用 template-driven forms 之前要把他的 module 引入进我们的 module 里来。

...
import { FormsModule }   from '@angular/forms';

@NgModule({
  ...
  imports: [
    BrowserModule,
    FormsModule
  ],
  ...
})
export class AppModule { }

然后就可以在我们的 Template 里添加 Form 了

<form>
  <div class="form-group">
    <label for="name">Name</label>
    <input type="text" class="form-control" id="name" required>
  </div>

  <div class="form-group">
    <label for="password">Password</label>
    <input type="password" class="form-control" id="password">
  </div>

  <button type="submit" class="btn btn-success">Submit</button>

</form>

这是一个 Form 表单最基本的形式,其中的 CSS classes form-group, form-control, 和 btn 是使用了 Twitter Bootstrap 框架。你可以通过链接添加到你的应用程序

@import url('https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css');

接下来就是把这个普通的 HTML 与 Angular Component 绑定起来。

Two-way data binding with ngModel

想要实现双向绑定,就要使用 Directive NgModel ,例如 <input [(ngModel)]="name" #ctrl="ngModel" required>。因为 NgModel 同时还会把自己暴露(exportAs)为一个变量名 ngModel ,所以我们可以把它转给 template reference variable 这里的叫做 ctrl ,那么就可以使用变量 ctrl 得到 input 对应的 ngModel 的详细属性了 <p>Valid: \{\{ ctrl.valid \}\}</p>

同样原理可以添加 Form 的 Directive 对象给变量 <form #userForm="ngForm"> 。这里并没有使用双向绑定的 Directive 呢,那是因为 Angular 自动为 form 标签的元素创建了 NgForm directive 。

下面是添加了双向绑定的 Template

<form #userForm="ngForm">
  <div class="form-group">
    <label for="name">Name</label>
    <input type="text" class="form-control" id="name" required [(ngModel)]="account.username" name="name">
  </div>

  <div class="form-group">
    <label for="password">Password</label>
    <input type="password" class="form-control" id="password" [(ngModel)]="account.password" name="password">
  </div>

  <button type="submit" class="btn btn-success">Submit</button>

</form>

States Control

下面就是根据各个变量的详细状态来控制界面显示,做到对用户更友善。为了方便查看变量或者 HTML element 状态的变化,你可以将他们输出到界面上,开发完后再去掉。例如下面为 input 添加变量 spy 用以查看他的 class name

<input type="text" class="form-control" id="name" required
       [(ngModel)]="account.username"
       name="name"
       #spy>
<br>TODO: remove this:

然后你就可以根据元素 Class Name 的实际变化添加不同的 CSS 代码,如

.ng-valid[required], .ng-valid.required  {
  border-left: 5px solid #42A948; /* green */
}

.ng-touched.ng-invalid:not(form)  {
  border-left: 5px solid #a94442; /* red */
}

再来看一下如何用控制变量控制界面上信息的显示

<input type="text" class="form-control" id="name" required
       [(ngModel)]="account.username"
       name="name"
       #name="ngModel">
<div [hidden]="name.valid || name.pristine" class="alert alert-danger">
  Name is required
</div>

更详细的和自定义输入校验请参考 Angular 官方文档 Form Validation

Submit the form with ngSubmit

Form 完成后就是提交动作了,使用监听 NgForm 的输出事件 ngSubmit 来做提交

<form (ngSubmit)="onSubmit()" #userForm="ngForm">

还可以为 Submit 按钮添加控制,当 Form 合法时才可以点击提交

<button type="submit" class="btn btn-success"
        [disabled]="!userForm.form.valid">Submit</button>

Reactive forms

Reactive forms is an Angular technique for creating forms in a reactive style.

References

Similar Posts

  • Angular - Syncfusion Components How to use Syncfusion Components to create dashboard page in Angular Application?
  • Angular - Consume OData Services How to consume odata service in Angular Application?
  • TypeScript TypeScript Series: Language Handbook
  • TypeScript - Decorators Decorators provide a way to add both annotations and a meta-programming syntax for class declarations and members.
  • Angular - UI5 Web Components The UI5 Web Components share fundamental UI5 qualities with others to provide enterprise-grade features, Fiori UX and themeability. The goal is to achieve an easy consumption of UI5 controls to lower the entry barrier to use UI5 controls for own applications and to avoid complexity of UI5 rendering-stack by making the consumption of the full-stack UI5 optional. In general, the UI5 Web Components are targeting for Web Developers who want to have more flexibility to use just HTML tags or arbitrary JS frameworks.
  • What's Functional Programming 什么是函数式编程 (Functional Programming)

Comments

Back to Top