Angular2文档学习的知识点摘要——显示数据、用户输入、表单

目录

显示数据

  在 Angular 中最典型的数据显示方式,就是把 HTML 模板中的控件绑定到 Angular 组件的属性

使用插值表达式显示组件属性

  1. 显示组件的属性,最简单的方式就是通过插值表达式 (interpolation) 来绑定属性名。 要使用插值表达式,就把属性名包裹在双花括号里放进视图模板,如{{myHero}}。
  2. 模板是包在 ECMAScript 2015 反引号 () 中的一个多行字符串。 反引号 () — 注意,不是单引号 (‘) — 允许把一个字符串写在多行上, 使 HTML 模板更容易阅读。

用户输入

  用户输入触发 DOM 事件。我们通过事件绑定来监听它们,把更新过的数据导入回我们的组件和 model。
1. 要绑定 DOM 事件,只要把 DOM 事件的名字包裹在圆括号中,然后用放在引号中的模板语句对它赋值就可以了。
2. 写绑定时,需要知道模板语句的执行上下文。 出现在模板语句中的每个标识符都属于特定的上下文对象。 这个对象通常都是控制此模板的 Angular 组件。
3. DOM 事件可以携带可能对组件有用的信息。如:通过 event4. event对象的属性取决于 DOM 事件的类型。
5. 当用户按下并释放一个按键时,触发keyup事件,Angular 在$event变量提供一个相应的 DOM 事件对象。在组件中使用event.target.value获取输入的值。
6. 所有标准 DOM 事件对象都有一个target属性, 引用触发该事件的元素。


模板引用变量

  还有另一种获取用户数据的方式:使用 Angular 的模板引用变量。 这些变量提供了从模块中直接访问元素的能力。 在标识符前加上井号 (#) 就能声明一个模板引用变量。

@Component({
  selector: 'key-up2',template: ` <input #Box (keyup)="onKey(Box.value)"> <p>{{values}}</p> `
})
export class KeyUpComponent_v2 {
  values = '';
  onKey(value: string) {
    this.values += value + ' | ';
  }
}

按键事件过滤

  1. (keyup)事件处理器监听每一次按键。 有时只在意回车键,因为它标志着用户结束输入。 解决这个问题的一种方法是检查每个$event.keyCode,只有键值是回车键时才采取行动。
  2. 更简单的方法是:绑定到 Angular 的keyup.enter 模拟事件。 然后,只有当用户敲回车键时,Angular 才会调用事件处理器。

表单

模板驱动的表单

  1. 如果组件、指令或管道出现在模块的imports数组中,不要把它声明在declarations数组中。 如果它是你自己写的,并且属于当前模块,就要把它声明在declarations数组中。
  2. 当在表单中使用[(ngModel)]时,必须要定义name属性
  3. 在内部,Angular 创建了一些FormControl,并把它们注册NgForm指令,再将该指令附加到标签注册每个FormControl时,使用name属性值作为键值。
  4. 每个 input 元素都有name属性,Angular 表单用它注册控件。
  5. 属性绑定中,值从模型中流动到屏幕上的目标属性 (property)。 通过把属性名括在方括号中来标记出目标属性,[]。 这是从模型到视图的单向数据绑定。
  6. 在事件绑定中,值从屏幕上的目标属性流动到模型。 通过把属性名括在圆括号中来标记出目标属性,()。 这是从视图到模型的反向单向数据绑定。
  7. Angular 选择了组合标点 [()] 来标记出双向数据绑定和双向数据流
  8. 事实上,可以把NgModel绑定拆成两个独立的绑定,如:<input type="text" class="form-control" id="name" required [ngModel]="model.name" name="name" (ngModelChange)="model.name = $event" >
      其中:ngModelChange并不是元素的事件。 它实际上是来自NgModel指令的事件属性
  9. 当 Angular 在表单中看到[(x)]的绑定目标时, 它会期待这个x指令有一个名为x的输入属性,和一个名为xChange的输出属性
  10. 模板表达式中的另一个古怪之处是model.name = $event。 之前看到的$event对象来自 DOM 事件。 但ngModelChange属性不会生成 DOM 事件 —— 它是Angular EventEmitter类型的属性,当它触发时, 它返回的是输入框的值 —— 也正是希望赋给模型name属性的值。
  11. 在表单中使用ngModel可以获得比仅使用双向数据绑定更多的控制权。它还会告诉我们很多信息:用户碰过此控件吗?它的值变化了吗?数据变得无效了吗?
  12. NgModel 指令不仅仅跟踪状态。它还使用特定的 Angular CSS 类来更新控件,以反映当前状态。 可以利用这些 CSS 类来修改控件的外观,显示或隐藏消息。
状态@H_400_301@ 为真时的CSS类@H_400_301@ 为假时的CSS类@H_400_301@
控件已经被访问过 ng-touched ng-untouched
控件值已经变化 ng-dirty ng-pristine
控件值是有效的 ng-valid ng-invalid

 13. 在控件上加入模板引用变量,通过模板引用变量.className可以查看当前控件所拥有的类。
 14. 模板引用变量可以访问模板中输入框的 Angular 控件。如:

<input type="text" required [(ngModel)]="model.name" name="name" #name="ngModel">

  这里,创建了名为name的变量,并且赋值为“ngModel”。
  注:为什么是“ngModel”?指令exportAs属性告诉Angular如何链接模板引用变量到指令。这里把name设置为ngModel是因为ngModel指令的exportAs属性设置成了“ngModel”。
 15. 在form表单上添加模板引用变量,并且赋值为ngForm,如:#heroForm="ngForm",现在heroForm变量引用的是NgForm指令,它代表的是表单的整体。可以在Angular表达式中使用该模板引用变量的reset方法,重置表单的状态。如:

<button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button>

.
 16. 什么NgForm指令?之前没有添加过 NgForm 指令啊!是 Angular 干的。Angular 自动创建了NgForm指令,并把它附加到标签
17. NgForm指令为form元素扩充了额外的特性。它持有通过ngModel指令和name属性为各个元素创建的那些控件,并且监视它们的属性变化,包括有效性。它还有自己的valid属性,只有当其中所有控件都有效时,它才有效。
18. 如可以通过heroForm变量(上述中提到的模板变量heroForm)把按钮的disabled属性绑定到表单的整体有效性。

<button type="submit" [disabled]="!heroForm.form.valid">Submit</button>

案例angular-forms

模型类 hero.ts

export class Hero {
    constructor(public id: number,public name: string,public power: string,public alterEgo?: string) {

    }
}

组件 hero-form.component.ts

import { Component } from '@angular/core';
import { Hero } from './hero';

@Component({
    moduleId: module.id,selector: 'hero-form',templateUrl: 'hero-form.component.html'
})
export class HeroFormComponent {
    powers = [
        'Really smart','Super Flexible','Super Hot','Weather Changer'
    ];

    model = new Hero(18,'Dr IQ',this.powers[0],'Chuck Overstreet');

    submitted = false;

    onSubmit() {
        this.submitted = true;
    }

    // TODO: Remove this when we're done
    get diagnostic() {
        return JSON.stringify(this.model);
    }

    newHero() {
        this.model = new Hero(42,'','');
    }
}

hero-form.component.html

<div class="container"> <div [hidden]="submitted"> <h1>Hero Form</h1> <form (ngSubmit)="onSubmit()" #heroForm="ngForm"> <!--{{diagnostic}}--> <div class="form-group"> <label for="name">Name</label> <input type="text" class="form-control" id="name" required [(ngModel)]="model.name" name="name" #name="ngModel"> </div> <div [hidden]="name.valid || name.pristine" class="alert alert-danger"> Name is required </div> <div class="form-group"> <label for="alterEgo">Alter Ego</label> <input type="text" class="form-control" id="alterEgo" [(ngModel)]="model.alterEgo" name="alterEgo"> </div> <div class="form-group"> <label for="power">Hero Power</label> <select id="power" class="form-control" required [(ngModel)]="model.power" name="power"> <option *ngFor="let pow of powers" [value]="pow">{{pow}}</option> </select> </div> <button type="submit" class="btn btn-default" [disabled]="!heroForm.form.valid">Submit</button> </form> <br/> <button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button> </div> <div [hidden]="!submitted"> <h2>You submitted the following:</h2> <div class="row"> <div class="col-xs-3">Name</div> <div class="col-xs-9 pull-left">{{ model.name }}</div> </div> <div class="row"> <div class="col-xs-3">Alter Ego</div> <div class="col-xs-9 pull-left">{{ model.alterEgo }}</div> </div> <div class="row"> <div class="col-xs-3">Power</div> <div class="col-xs-9 pull-left">{{ model.power }}</div> </div> <br> <button class="btn btn-default" (click)="submitted=false">Edit</button> </div> </div>

注:使用到ngModel时,需要在控件上添加name属性

根模块 app.module.ts

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

import { AppComponent }  from './app.component';
import { HeroFormComponent } from './hero-form.component';

@NgModule({
  imports:      [ BrowserModule,FormsModule ],declarations: [ AppComponent,HeroFormComponent ],bootstrap:    [ AppComponent ]
})
export class AppModule { }

注:因为模板驱动的表单位于它们自己的模块,所以在使用表单之前,需要将FormsModule添加到应用模块的imports数组中。

根组件 app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',template: `<hero-form></hero-form>`,})
export class AppComponent { }

引导根模块 main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

示例页面 index.html

  在index.html页面的body标签添加

<my-app>Loading AppComponent content here ...</my-app>

定制CSS类,提供无效控件的视觉反馈 forms.css

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

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

相关文章

AngularJS 是一个JavaScript 框架。它可通过 注:建议把脚本放在 元素的底部。这会提高网页加载速度,因...
angluarjs中页面初始化的时候会出现语法{{}}在页面中问题,也即是页面闪烁问题。出现这个的原因是:由于...
AngularJS 通过被称为指令的新属性来扩展 HTML。AngularJS 指令AngularJS 指令是扩展的 HTML 属性,带有...
AngularJS 使用表达式把数据绑定到 HTML。AngularJS 表达式AngularJS 表达式写在双大括号内:{{ expres...
ng-repeat 指令可以完美的显示表格。在表格中显示数据 {{ x.Name }} {{ x.Country }} 使用 CSS 样式为了...
$http是 AngularJS 中的一个核心服务,用于读取远程服务器的数据。读取 JSON 文件下是存储在web服务器上...