指令
ng 的指令允许你向 HTML 元素中添加定制功能。非组件指令(组件是一种特殊的指令)通常对现有元素进行修改,进一步可分为两种类型:
属性指令
属性指令可改变元素或者组件的外观、样式和行为。比如
ngClass
和ngStyle
用于绑定样式。结构化指令
结构化指令,可通过控制元素的渲染,来改变页面的布局。比如
ngIf
和ngFor
。
内置属性指令
通常我们使用类名来称呼指令,所以我们在书写指令时,使用的是
大驼峰
的风格,比如NgClass
。而在使用时,采用小驼峰
的形式,比如<div [ngClass]="myClass"></div>
。
NgClass
和 NgStyle
是两个处理样式的内置指令,使用它们,可灵活地绑定元素或者组件的样式,类似于 vue 中的 class
和 style
。
class 属性绑定的缺点?
当需要根据条件来绑定多个类时,我们需要根据条件来生成多个字符串,随着条件的增加,代码变得不好维护,而 NgClass
可解决这一问题。
NgClass 接收一个对象作为输入,键是一个类名,而键值是布尔。 键值为假值, ng 会把对应的键从元素 class 属性中删除,为真值则把对应的键添加到 class 属性中。
NgClass 在使用时,可以和元素的 class 属性一起使用,NgClass 不会覆盖原来的 class,而是智能合并。
在元素应用不同类的情况时,NgClass 容易计算和理解,容易进行单元测试。
NgStyle
和 NgClass 非常相似,接收一个对象,对象的键时 CSS 属性,键值是 CSS 属性值,也可是一个表达式,ng 会把对象编译成行内样式,这和 Vue 的 style 极为相似。
h3 [ngStyle]="nameStyle">{{stock.name}}</h3>
TS 代码
this.nameStyle = {
color: "red",
width: largeChange ? "150px" : "150px",
"font-size": "1.5em",
backgroundColor: "yellow",
};
在书写有
-
的样式属性时,需要转为小驼峰式或者引号包裹原来的属性。
内联样式的绑定语法,需要写很多代码,当样式很多时,会比较繁琐,不推荐这种写法。
绑定样式的另一种写法:
[class.class-name]="expression" [style.css-property]="expression"
当表达式为真值时,类名或者 css 属性会应用到元素上。
结构化指令
结构化指令可控制 DOM 元素的渲染,从而改变页面的布局。
结构化指令遵循一种特殊的语法--- 以 *
开头,很容易和属性绑定和事件绑定区分。
常见的结构化指令:
- NgIf --- 条件渲染。
- NgSwitch --- 多条件渲染。
- NgFor --- 渲染列表。
<h1 *ngIf="showTitle">hello {{title}}</h1>
<hr />
<ul [ngSwitch]="howAreYou">
<li *ngSwitchCase="'great'">great</li>
<li *ngSwitchCase="'good'">good</li>
<li *ngSwitchCase="'notBad'">notBad</li>
<li *ngSwitchCase="'bad'">bad</li>
<li *ngSwitchDefault>well</li>
</ul>
<hr />
<ul>
<li *ngFor="let item of list;let i = index;trackBy:trackByMethod">
{{i}} -- {{item}} -- {{trackBy}}
</li>
</ul>
NgSwitch
实际上不是一个结构指令,而是属性指令,和 JS 里的 switch
语法类似,有一个 NgSwitchCase
和 NgSwitchDefault
结合使用,该指令类似 vue 中的 v-if v-else-if v-else
。
NgFor
用于循环渲染列表元素,表达式是一个 of 循环,可通过另外一个语句获取元素的下标,可提供一个 trackBy
来追踪每个元素,在列表重新渲染时,会根据它来决定是否重用 DOM ,从而提高性能,它接收一个函数,该函数返回一个唯一的值,提供给 ng 用来追踪元素。类似 vue 中 v-for
中的 key。
可以把 ngFor 和 ngIf 同时用在一个元素上吗?
ng 不支持多个指令用到同一个元素上,因为这样会不清楚哪个指令先执行,ng 是禁止这样做的,否则报错。
使用
ng-container
包裹希望条件渲染的元素。
有如下数组,想要渲染 isGood
为 true 的元素,可以这样写:
[
{ tech: "jquery", isGood: true },
{ tech: "angular", isGood: true },
{ tech: "react", isGood: false },
{ tech: "vue", isGood: false },
];
<ul>
<ng-container *ngFor="let item of list">
<li *ngIf="item.isGood">{{item.tech}}</li>
</ng-container>
</ul>
更多阅读:
Angular ng-template, ng-container and ngTemplateOutlet - The Complete Guide To Angular Templates
https://stackoverflow.com/questions/39547858/ng-container-vs-template
项目报错:Can't bind to 'ngForOf' since it isn't a known property of 'ng-container'. 然后报错消失,奇怪。
如何写自定义指令?