官方文档
1. NgModel - 使用[(ngModel)]双向绑定到表单元素
当开发数据输入表单时,你通常都要既显示数据属性又根据用户的更改去修改那个属性。
//src/app/app.component.html
<input [(ngModel)]="title">
[(ngModel)]内幕
ngModel 指令通过自己的输入属性 ngModel 和输出属性 ngModelChange 隐藏了那些细节
//src/app/app.component.html
<input
[ngModel]="title"
(ngModelChange)="title=$event">
[(ngModel)] 语法只能设置数据绑定属性。 如果要做更多或者做点不一样的事,也可以写它的展开形式。
//src/app/app.component.html
<input
[ngModel]="title"
(ngModelChange)="setUpper($event)">
下面这个生造的例子强制输入框的内容变成大写:
//src/app/app.component.ts
...
export class AppComponent {
title = 'Tour of Heroes';
constructor(){};
setUpper(event:any){
this.title = event.toUpperCase();
}
}
注:1.要使用ngModel双向绑定,需要在该component所隶属的module里写,如,该component在app包下,跟模块是app.module.ts(AppModule)里导入
import { FormsModule } from '@angular/forms';
@NgModule下的imports:里导入:@NgModule({imports: [FormsModule]})
; 如果,该component在你自己定义的包下,如在heroes包下,而heroes又有自己的HeroesModule,那么刚才的操作方式要放在HeroesModule下,要不然还会报错。
2. 创建新目录,并在该目录下创建一个带路由的 HeroesModule,并把它注册进 AppModule 中命令:该命令是建一个heroes目录,并创建一个herosModule
ng generate module heroes/heroes --module app --flat --routing
2.内置结构型指令
2.1 *ngIf
当 NgIf 为 false 时,Angular 从 DOM 中物理地移除了这个元素子树。 它销毁了子树中的组件及其状态,也潜在释放了可观的资源,最终让用户体验到更好的性能。
防范空指针错误
2.2 *ngFor
NgFor 指令上下文中的 index 属性返回一个从零开始的索引,表示当前条目在迭代中的顺序。 你可以通过模板输入变量捕获这个 index 值,并把它用在模板中。
<div *ngFor="let hero of heroes; let i=index">{{i + 1}} - {{hero.name}}</div>
2.3 [ngSwitch]
绑定到 [ngSwitch]。如果试图用 *ngSwitch 的形式使用它就会报错, 这是因为 NgSwitch 是一个属性型指令,而不是结构型指令。 它要修改的是所在元素的行为,而不会直接接触 DOM 结构。
<div [ngSwitch]="currentHero.emotion">
<app-happy-hero *ngSwitchCase="'happy'" [hero]="currentHero"></app-happy-hero>
<app-sad-hero *ngSwitchCase="'sad'" [hero]="currentHero"></app-sad-hero>
<app-confused-hero *ngSwitchCase="'confused'" [hero]="currentHero"></app-confused-hero>
<app-unknown-hero *ngSwitchDefault [hero]="currentHero"></app-unknown-hero>
</div>
3. 模板引用量
使用井号 (#) 来声明引用变量。 #phone 的意思就是声明一个名叫 phone 的变量来引用 元素。
<input #phone placeholder="phone number">
<button (click)="callPhone(phone.value)">Call</button>
大多数情况下,Angular 会把模板引用变量的值设置为声明它的那个元素
你也可以用 ref- 前缀代替 #。 下面的例子中就用把 fax 变量声明成了 ref-fax 而不是 #fax。
<input ref-fax placeholder="fax number">
<button (click)="callFax(fax.value)">Fax</button>
4. 输入和输出属性
输入属性是一个带有 @Input 装饰器的可设置属性。当它通过属性绑定的形式被绑定时,值会“流入”这个属性。
输出属性是一个带有 @Output 装饰器的可观察对象型的属性。 这个属性几乎总是返回 Angular 的EventEmitter。 当它通过事件绑定的形式被绑定时,值会“流出”这个属性。
你只能通过它的输入和输出属性将其绑定到其它组件或指令。
4.1 绑定到其它组件
这种绑定形式下,其它组件的属性位于等号(=)的左侧。
//src/app/app.component.html
<app-hero-detail [hero]="currentHero" (deleteRequest)="deleteHero($event)">
</app-hero-detail>
// src/app/hero-detail.component.ts
@Input() hero: Hero;
@Output() deleteRequest = new EventEmitter<Hero>();
另外,还可以在指令元数据的 inputs 或 outputs 数组中标记出这些成员。比如这个例子:
// src/app/hero-detail.component.ts @Component({ inputs: ['hero'], outputs: ['deleteRequest'], })
4.2 输入还是输出?
输入属性通常接收数据值。 输出属性暴露事件生产者,如 EventEmitter 对象。
输入和输出这两个词是从目标指令的角度来说的。
4.3 给输入/输出属性起别名
有时需要让输入/输出属性的公共名字不同于内部名字。
这是使用 attribute 指令时的常见情况。 指令的使用者期望绑定到指令名。例如,在 <div> 上用 myClick 选择器应用指令时, 希望绑定的事件属性也叫 myClick。
//src/app/app.component.html
<div (myClick)="clickMessage=$event" clickable>click with myClick</div>
//src/app/click.directive.ts
@Output('myClick') clicks = new EventEmitter<string>(); // @Output(alias) propertyName = ...
也可在 inputs 和 outputs 数组中为属性指定别名。 可以写一个冒号 (? 分隔的字符串,左侧是指令中的属性名,右侧则是公共别名。
//src/app/click.directive.ts @Directive({ outputs: ['clicks:myClick'] // propertyName:alias })
5 模板表达式操作符
5.1管道操作符
eg:
<div>Title through uppercase pipe: {{title | uppercase}}</div>
<!-- Pipe chaining: convert title to uppercase, then to lowercase -->
<div>
Title through a pipe chain:
{{title | uppercase | lowercase}}
</div>
还能对它们使用参数:
<!-- pipe with configuration argument => "February 25, 1970" -->
<div>Birthdate: {{currentHero?.birthdate | date:'longDate'}}</div>
json 管道对调试绑定特别有用:
<div>{{currentHero | json}}</div>
输出:
{ "id": 0, "name": "Hercules", "emotion": "happy",
"birthdate": "1970-02-25T08:00:00.000Z",
"url": "http://www.imdb.com/title/tt0065832/",
"rate": 325 }
5.2安全导航操作符 ( ?. ) 和空属性路径
用来保护出现在属性路径中 null 和 undefined 值。 下例中,当 currentHero 为空时,保护视图渲染器,让它免于失败。
The current hero's name is {{currentHero?.name}}