Angular踩坑 常见的值检测/Change机制
一般常用的值检测和值改变机制
*ngif="" [ngif]=""
这是angular最常用的一种移除/添加标签的方法,也是最直接的方法。
ngif其实是一种表达式,如果表达式的结果为false,则所在的标签移除,反之则为添加。
<!--一般用法-->
<div *ngIf="condition">Content to render when condition is true.</div>
<!--else template用法-->
<div *ngIf="condition; else elseBlock">...</div>
<ng-template #elseBlock>...</ng-template>
<!--then 和 else template用法-->
<div *ngIf="condition; then thenBlock else elseBlock"></div>
<ng-template #thenBlock>...</ng-template>
<ng-template #elseBlock>...</ng-template>
// ts部分
export class componentComponent implements OnInit {
condition = true;
}
ngOnChanges()方法
ngOnChanges方法我一般用在组件传值使用,直接看我写的例子代码:
<!--子组件html-->
<!--app-strategy-control标签是用了selector装饰器,用来实例化component-->
<!--[]包含的是传的值,()包含的是调用的方法-->
<div nz-col nzLg="18" class="strategy-form" *ngIf="strategies.length > 0">
<app-strategy-control [strategyId]="selectedStrategyId" [areaId]="areaId"
[areaType]="areaType"
(onStrategyUpdated)="strategyUpdate()"
(onModalClosed)="closeModal()"
></app-strategy-control>
</div>
// 父组件ts
import { Component, EventEmitter, Inject, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
@Component({
selector: 'app-strategy-control', // 装饰器
templateUrl: './strategy-control.component.html',
styleUrls: ['./strategy-control.component.less'],
})
export class StrategyControlComponent implements OnChanges {
@Input() // 接受子组件传过来的值
areaType: string;
@Input()
areaId: number;
@Input()
strategyId: number;
@Output() // 调用子组件的方法
onStrategyUpdated = new EventEmitter<void>();
@Output()
onModalClosed = new EventEmitter<void>();
ngOnChanges(changes: SimpleChanges): void {
// 监测@Input传过来的值,如果有变化就会执行这里面的方法
/*注意 ngOnChanges的生命周期执行的顺序在ngOnInit之前*/
}
}
changeDetection:ChangeDetectionStrategy.OnPush
当组件实例化之后,Angular 就会创建一个变更检测器,它负责传播组件各个绑定值的变化。 该策略是下列值之一:
- ChangeDetectionStrategy#OnPush 把策略设置为 CheckOnce(按需)。
- ChangeDetectionStrategy#Default 把策略设置为 CheckAlways。
上面是Angular官方的说明,例如搜索一个表格数据的时候,你点击了搜索,但是表格的结果并没有变化,看控制台是有请求发出并且成功获取数据了,这就是ChangeDetectionStrategy.OnPush在作祟。
当属性为OnPush时,在实际业务中,只有数据产生变化或者有事件产生变化才会进行更新渲染,这也是我踩到的坑之一,当初调试了好久都没发现ts代码有一行这个:
import {ChangeDetectionStrategy,Component,EventEmitter,Inject,Input,OnChanges,Output,SimpleChanges,} from '@angular/core';
@Component({
selector: 'app-strategy-control',
changeDetection: ChangeDetectionStrategy.OnPush, // 就是这行代码
templateUrl: './strategy-control.component.html',
styleUrls: ['./strategy-control.component.less'],
})
export class StrategyControlComponent implements OnChanges {
}
*ngfor
ngfor类似于VUE的v-for,功能我就不多介绍了,这里讲一个技巧,当需要加载的数据量过多时,但是页面加载的速度比收到请求的速度快,就会造成报错,这个时候就需要在HTML的模板属性后面加个**?**,这个例子是显示对象的数据,数组同理:
<!--可在模板属性后面加? 就可以避免页面加载出来了,但是数据还未加载出来的报错-->
<div class="hfx-weather">
<img [src]="officialLiveWeather?.weatherIcon">
<span>实况天气:{{officialLiveWeather?.text}}</span>
<span>实况温度:{{officialLiveWeather?.temp}}℃</span>
<span>实况风向:{{officialLiveWeather?.windDir}}</span>
<span>实况风力等级:{{officialLiveWeather?.windScale}}</span>
<span>实况相对湿度:{{officialLiveWeather?.humidity}}%</span>
<span>观测时间:{{officialLiveWeather?.updateTime}}</span>
</div>
这个方法类似于ts的调用方法传值:
export class StrategyControlComponent implements OnChanges {
ngOnChanges(changes: SimpleChanges): void {
this.loadData();
}
loadData(num?: number){ // ?代表可传可不传参数
}
}