0%

ng2内置指令

内置指令,分为属性型指令和机构型指令。

内置属性型指令

属性型指令通常会监听和修改其他html元素或组件的行为、元素属性(Attribute)、DOM属性(Property)。

几个常见的属性型指令:

  • NgClass 添加或移除一组css类
  • NgStyle 添加或移除一组css样式
  • NgModle 双向绑定到html表单元素

NgClass指令

通过NgClass,可以同时添加或移除多个类。

处理单个的类时,可以使用[class.class-name],处理多个类的时候,[ngClass]是最好的选择。

1
<h3 [ngClass]="currentClass">Hero list</h3>
1
2
3
4
this.currentClass = {
bad: true,
cursor: true,
};
1
2
3
4
5
6
.bad {
color: red;
}
.cursor{
cursor: not-allowed;
}

控制对象是一个key:value形式的对象,key是类名,value是值,如果value的值是true,这个类就会被加上,否则会被移除。

ngStyle指令

使用ngStyle指令可以同时设置多个内联样式。

样式绑定是设置单一样式值的简单方法:

1
<div class="face" [style.background-image]="'url(' + hero.face + ')'" [style.background-color]="'red'"></div>

这样设置简单的是可以的,但是要设置多个,就很麻烦了,我们可以使用ngStyle。

ngStyle需要绑定到一个key:value控制的对象,key是样式名,value是用于这个样式的值:

1
2
3
4
5
6
<div class="face" [ngStyle]="{
'background-image': 'url(' + hero.face + ')',
'background-color': 'red',
'background-size': 'cover'
}
"></div>

ngModel指令

当开发数据表单时,我们需要即显示数据也要修改那个属性,这时候可以使用ngModel指令进行双向绑定。使用ngModel时需要引入FormsModule,将FormsModule加入到imports列表中。注意是在模块moduleimport数组里面,不是组件。

1
<input [(ngModel)]="myHero.name" />

ngModel指令只支持实现了ControlValueAccessor的元素,它们能让元素适配本协议。angular为所有的基础html表单都提供了值访问器(value accessor)。我们不能把[(ngModel)]用到非表单类的原生元素或自定义组件上,除非写一个合适的值的访问器。

内置结构型指令

结构型指令的职责是html布局。通过添加、移除和操纵他们所附加到的宿主元素来实现重塑DOM的结构。常见的有:

  • ngIf 根据条件显示添加DOM或移除DOM
  • ngSwitch 用于切换一组视图
  • ngForOf 对列表中的每个条目重复使用同一套模板

ngIf指令

通过把ngIf指令应用到宿主元素上,我们可以往DOM中添加或移除这个元素。

1
<h2 *ngIf="hero.name == myHero.name">this is my super hero!</h2>

ngIf应用到组件上的时候,如果移除组件会销毁该组件和所有子组件。我们可以控制样式来显示或隐藏元素,但ngIf的添加、移除和显示、隐藏是不同的概念。

当ngIf为false时,angular从DOM中物理的移除这个元素子树,并销毁子树中的组件和状态,也释放了可观的资源,最终让用户体验到了更好的性能,对于大型组件树,ngIf相对来讲是个更安全的选择。

ngFor指令

ngFor是个重复器指令–自定义数据显示的一种方式。我们的目标是展示一个有多个条目的列表,首先定义一个html块,它规定单个条目如何显示,再告诉angular把这个块当做模板,渲染列表中的每个条目。

1
2
3
<div *ngFor="let hero of heroes">
<span>{{hero.zh_name}}: {{hero.name}}</span>
</div>

赋值给*ngFor的字符串不是模板表达式,而是一个微语法–由angular自己解释的小型语言。angular把这个指令翻译成了一个<ng-template>包裹的宿主元素,然后使用这个模板重复创建出一组新元素,并绑定到列表中的每一个hero

微语法里面的let关键字创建了一个名叫hero的模板输入变量。ngFor指令在属性heroes数组上迭代,每次迭代都从数组中把当前元素赋值给heor变量。

ngFor指令上下文中的index属性返回一个从零开始的索引,表示在当前迭代中的顺序。

1
2
3
<div *ngFor="let hero of heroes; let i = index">
<span>Number:{{i + 1}} {{hero.zh_name}}: {{hero.name}}</span>
</div>

ngFor指令有时候性能较差,特别是在大型列表中,对应一个条目的一个改动、移除、或添加,都会导致所有的这个ngFor级联的DOM会重新渲染。

我们可以通过提供trackBy函数来追踪添加或删除的条目,trackBy方法需要index和当前迭代的item作为参数,并需要返回对应item的唯一标志。

1
2
3
<div *ngFor="let hero of heroes; trackBy: trackByFun; let i = index;">
<span>Number:{{i + 1}} {{hero.zh_name}}: {{hero.name}}</span>
</div>
1
2
3
trackByFun(index: number, hero: Hero): string {
return hero.name;
}

这样,数据源heroes发生变动时,检测到是一个name,就不会清理DOM,反之,就清理旧的,添加新的。

ngSwitch指令

ngSwitch指令类似于JavaScript的switch语句。可以从多个可能的元素中根据switch的条件来显示某一个。angular会把选中的元素放入DOM中。包含三个相互协作的指令:

  • ngSWitch 主控指令,绑定到一个返回候选值的表达式,候选值可以是任意类型,是属性指令,用法:[ngSwitch]
  • ngSwitchCase 绑定的值等于候选值时,把它插入到DOM中,结构型指令,用法:*ngSwitchCase
  • ngSwitchDefault 没有任何一个ngSwitchCase时把它所在的元素加入到DOM中,结构型指令,用法:*ngSwitchDefault
1
2
3
4
<div [ngSwitch]="selectHero.name">
<div *ngSwitchCase="'Iron Man'">激光炮</div>
<div *ngSwitchDefault>敬请期待</div>
</div>
码字辛苦,打赏个咖啡☕️可好?💘