HTML是没有条件控制的语言,如果要根据某变量的值显示或隐藏某个DOM元素,往往需要结合JavaScript的if-else表达式来控制。
Angular ngIf就可以增强Html这方面的能力。ngIf接受一个表达式作为值,并且强制把表达式计算出的值转换为Boolean类型,如果值为true,则在DOM中渲染模板,如果值为false则不渲染ngIf所在的模板。
示例:
<div class="container" *ngIf="userLoggedIn">
<h2>欢迎登录</2>
<p>使用说明。。。。。</p>
</div>
示例中如果用户登录了,则显示出欢迎语。是否登录有userLoggedIn的值确定,userLoggeIn的值为true,则表示登录,false表示未登录。
应用ngIf的位置
应用ngIf的位置分为两种:
- 模板存在容器父元素,即一个父元素,包含了所有是否要显示或隐藏的其他元素,这种情况ngIf放置在父元素上。
-
模板没有容器元素,可以使用
<ng-container>
把其他元素包含在内,然后ngIf应用在<ng-container>
上。
上面示例div就是一个容器元素。所以ng应用在它上面就可以了。
但模板没有容器元素,把ngIf应用在<ng-container>上,这样就可以控制显示或隐藏<ng-container>里的元素。而不需要额外添加其他类似div的父元素。
<ng-container *ngIf="userLoggedIn">
<h2>欢迎登录</2>
<p>使用说明。。。。。</p>
</ng-container>
ngIf 接受表达式的类型
ngIf不仅仅接受布尔表达式,还可以接受任意有效的TypeScript表达式,只要表达式能够转化为Boolean值就可以。它会根据表达式转换的Boolean值来决定是否渲染模板元素。
ngIf可以接受表达式的类型:布尔表达式,字符串,数组,对象以及数字等等。这个和JavaScript里if
检测表达式是否为真是相同的。。
数字和字符串示例:
<div class="container" *ngIf="10">
10表示为True,结果显示
</div>
<div class="container" *ngIf="0">
0表示为False,结果隐藏
</div>
<div class="container" *ngIf="'hello world'">
非空字符串为True,结果显示
</div>
<div class="container" *ngIf="''">
空字符串为False,结果隐藏
</div>
数组和对象示例:
<div class="container" *ngIf="{hello: 'world'}">
非null或undefined对象为True,结果显示
</div>
<div class="container" *ngIf="{}">
空对象为True,结果显示
</div>
<div class="container" *ngIf="[1, 2 ,3]">
数组对象为True,结果显示
</div>
<div class="container" *ngIf="[]">
空数组为True,结果显示
</div>
数组和对象是否为true,是依据它的值是否为null或者undefined。
ngIf else语法
除了使用ngIf用于控制显示/隐藏外,有些情况需要使用else语句来控制显示的内容。
语法如下:
<div *ngIf="condition; else elseBlockId">
condition条件为True,显示此内容
</div>
<ng-template #elseBlockId>
condition条件为False,则显示此由elseBlock标记的模板内容。
</ng-template>
ngIf用于判断的表达式condition使用分号(;)与else关键词隔开,else后为标记模板id,示例为elseBlockId。<ng-template>使用elseBlockId标记,定义了条件为false,else要显示的内容。
ngIf then else语法
除了直接在ngIf容器元素内定义条件为true显示的内容外,可以使用then关键词,定义条件为true时显示的内容。是ngIf else的变种写法:
<div *ngIf="condition; then thenBlock else elseBlock"></div>
<ng-template #thenBlock>
condition条件为True,显示thenBlock内容
</ng-template>
<ng-template #elseBlock>
condition条件为False,显示elseBlock内容
</ng-template>
在ngIf表达式种使用Observable数据
如果是基于RxJs写的应用吗,在模板种使用的数据通常是使用Observable提供。
ngIf 指令可以结合async pipe来使用 Observable,如以下示例:
<ng-container *ngIf="(user$ | async) as user">
<span>用户名:</span>
<span class="profile">{{user.name}}</span>
</ng-container>
示例中user$是一个Observable数据。不同于原始数据,Observable数据需要通过async管道来订阅,当Observable有数据发出,就会触发async的订阅。as user
是把Observable发出的数据赋值给模板的本地变量user。
在模板中使用Observable有以下好处:
- 当组件被销毁时,async管道会自动取消订阅 Observable。
- 如果使用 OnPush 更改检测策略,组件视图将使用最新的 Observable 数据自动更新。
ngIf指令的语法糖
ngIf实际是ngIf指令的语法糖。其中前缀星号*,表示ngIf指令是一种结构性指令。
Angular在编译时,会把*表示的结构性执行编译为初始的形式,如*ngIf示例:
<div class="container" *ngIf="condition; else elseBlock">
... Angular会解糖(de-sugar)*ngIf语法
</div>
<ng-template #elseBlock>
condition为false,显示此内容
</ng-template>
解糖为<ng-template>为:
<ng-template [ngIf]="condition" [ngIfElse]="elseBlock">
<div class="container">
... Angular会解糖(de-sugar)*ngIf语法
</div>
</ng-template>
<ng-template #elseBlock>
condition为false,显示此内容
</ng-template>