NgIf
根据 expression
表达式的值,有条件的包含某个模板。
Conditionally includes a template based on the value of an expression
.
NgModule
选择器
[ngIf]
属性
属性 | 说明 |
---|---|
@Input() | Write-only. |
@Input() | Write-only. |
@Input() | Write-only. |
说明
ngIf
会对 expression
进行求值,如果为真,则在原地渲染 then
模板,否则渲染 else
模板。通常:
ngIf
evaluates the expression
and then renders the then
or else
template in its place when expression is truthy or falsy respectively. Typically the:
then
模板就是ngIf
中内联的模板 —— 除非你指定了另一个值。then
template is the inline template ofngIf
unless bound to a different value.else
模板是空白的 —— 除非你另行指定了。else
template is blank unless it is bound.
常见用法
Most common usage
ngIf
指令最常见的用法是根据条件显示其内联模板,比如:
The most common usage of the ngIf
directive is to conditionally show the inline template as seen in this example:
通过 else
显示另一个模板
Showing an alternative template using else
如果 expression
为假时有必要显示一个模板,就可以用上述的 else
模板来进行绑定。 注意,else
绑定指向的是一个带有 #elseBlock
标签的 <ng-template>
元素。 该模板可以定义在此组件视图中的任何地方,但为了提高可读性,通常会放在 ngIf
的紧下方。
If it is necessary to display a template when the expression
is falsy use the else
template binding as shown. Note that the else
binding points to a <ng-template>
labeled #elseBlock
. The template can be defined anywhere in the component view but is typically placed right after ngIf
for readability.
- @Component({
- selector: 'ng-if-else',
- template: `
- <button (click)="show = !show">{{show ? 'hide' : 'show'}}</button>
- show = {{show}}
- <br>
- <div *ngIf="show; else elseBlock">Text to show</div>
- <ng-template #elseBlock>Alternate text while primary text is hidden</ng-template>
- `
- })
- class NgIfElse {
- show: boolean = true;
- }
使用非内联的 then
模板
Using non-inlined then
template
通常,then
模板就是 ngIf
的内联模板,不过你也可以通过绑定机制(就像 else
那样)来修改它。 因为 then
和 else
都是绑定,因此可以在运行期间改变这个模板引用 —— 如下例所示。
Usually the then
template is the inlined template of the ngIf
, but it can be changed using a binding (just like else
). Because then
and else
are bindings, the template references can change at runtime as shown in this example.
- @Component({
- selector: 'ng-if-then-else',
- template: `
- <button (click)="show = !show">{{show ? 'hide' : 'show'}}</button>
- <button (click)="switchPrimary()">Switch Primary</button>
- show = {{show}}
- <br>
- <div *ngIf="show; then thenBlock; else elseBlock">this is ignored</div>
- <ng-template #primaryBlock>Primary text to show</ng-template>
- <ng-template #secondaryBlock>Secondary text to show</ng-template>
- <ng-template #elseBlock>Alternate text while primary text is hidden</ng-template>
- `
- })
- class NgIfThenElse implements OnInit {
- thenBlock: TemplateRef<any>|null = null;
- show: boolean = true;
-
- @ViewChild('primaryBlock')
- primaryBlock: TemplateRef<any>|null = null;
- @ViewChild('secondaryBlock')
- secondaryBlock: TemplateRef<any>|null = null;
-
- switchPrimary() {
- this.thenBlock = this.thenBlock === this.primaryBlock ? this.secondaryBlock : this.primaryBlock;
- }
-
- ngOnInit() { this.thenBlock = this.primaryBlock; }
- }
把条件结果保存在变量中
Storing conditional result in a variable
一种常见的需求模式为:我们要显示来自同一个对象的一组属性。如果该对象是 undefined,那么我们就不得不使用安全遍历操作符 ?.
来防止引用到空对象。 尤其是在使用 async
管道等待异步数据时,例如:
A common pattern is that we need to show a set of properties from the same object. If the object is undefined, then we have to use the safe-traversal-operator ?.
to guard against dereferencing a null
value. This is especially the case when waiting on async data such as when using the async
pipe as shown in following example:
Hello {{ (userStream|async)?.last }}, {{ (userStream|async)?.first }}!
上面这个例子中有一系列低效代码:
There are several inefficiencies in the above example:
我们在
userStream
上创建了多个订阅。每个async
管道都有一个,比如上面这个例子中就用了两个。We create multiple subscriptions on
userStream
. One for eachasync
pipe, or two in the example above.在等待异步数据到来的时候,我们没法显示一个备用视图(如 loading)。
We cannot display an alternative screen while waiting for the data to arrive asynchronously.
我们不得不使用安全遍历操作符
?.
来访问属性,太繁琐了。We have to use the safe-traversal-operator
?.
to access properties, which is cumbersome.我们不得不把
async
管道放进圆括号里。We have to place the
async
pipe in parenthesis.
更好的方式是使用 ngIf
,并把该条件的结果存到局部变量里,例如:
A better way to do this is to use ngIf
and store the result of the condition in a local variable as shown in the the example below:
- @Component({
- selector: 'ng-if-let',
- template: `
- <button (click)="nextUser()">Next User</button>
- <br>
- <div *ngIf="userObservable | async as user; else loading">
- Hello {{user.last}}, {{user.first}}!
- </div>
- <ng-template #loading let-user>Waiting... (user is {{user|json}})</ng-template>
- `
- })
- class NgIfAs {
- userObservable = new Subject<{first: string, last: string}>();
- first = ['John', 'Mike', 'Mary', 'Bob'];
- firstIndex = 0;
- last = ['Smith', 'Novotny', 'Angular'];
- lastIndex = 0;
-
- nextUser() {
- let first = this.first[this.firstIndex++];
- if (this.firstIndex >= this.first.length) this.firstIndex = 0;
- let last = this.last[this.lastIndex++];
- if (this.lastIndex >= this.last.length) this.lastIndex = 0;
- this.userObservable.next({first, last});
- }
- }
注意:
Notice that:
我们只用了一个
async
管道,因此也只会进行一次订阅。We use only one
async
pipe and hence only one subscription gets created.ngIf
把userStream|async
的结果保存在了局部变量user
中。ngIf
stores the result of theuserStream|async
in the local variableuser
.局部变量
user
可以反复绑定 —— 这很高效。The local
user
can then be bound repeatedly in a more efficient way.不需要使用安全遍历操作符
?.
来访问属性,因为ngIf
只有在userStream
有数据时才会显示内容。No need to use the safe-traversal-operator
?.
to access properties asngIf
will only display the data ifuserStream
returns a value.在等待数据到达时,我们可以显示一个代用模板。
We can display an alternative template while waiting for the data.
语法
Syntax
简单形式:
Simple form:
带有 else
块的形式:
Form with an else block:
<div *ngIf="condition; else elseBlock">...</div>
<ng-template #elseBlock>...</ng-template>
带有 then
和 else
块的形式:
Form with a then
and else
block:
<div *ngIf="condition; then thenBlock else elseBlock"></div>
<ng-template #thenBlock>...</ng-template>
<ng-template #elseBlock>...</ng-template>
保存到局部变量的形式:
Form with storing the value locally:
<div *ngIf="condition as value; else elseBlock">{{value}}</div>
<ng-template #elseBlock>...</ng-template>
静态方法
Assert the correct type of the expression bound to the |
The presence of this method is a signal to the Ivy template type check compiler that when the |