三個框架,都有響應式數據的概念。在angular里面有專門的叫法,響應式數據叫信號
,英文名signal。其他兩個框架式沒有專門的名字的,統稱為動態數據。這點可以說,angular還是太細了,細節值得點贊!!
那么,信號也就是響應式數據在ng里面該怎么使用呢?
實現效果
代碼實現
- 省略無關代碼,核心包中引入
signal
這個api,包裝我們需要做成響應式的數據
import { Component, signal } from '@angular/core';
money = signal(100);handleChangeAge = () => {this.money.update((v) => v + 100);
};
- 頁面上使用
<p>我銀行賬戶的存款:{{money()}}</p>
<button (click)="handleChangeAge()">改變年齡</button>
注意:
- 頁面上使用的使用,無論是響應式數據還是方法的調用都要加上
()
,否則頁面上無法顯示,這點跟其他兩個框架略有差別。 - ng中事件綁定用的是
(enventType) = "enventName()"
- 動態屬性用的是
[attrName] = "attrName2"
計算屬性
根據已有的值計算出新的一個值,這樣我們就可以用到computed
這個api,這個屬性是惰性的,之前的計算結果會被緩存,如果再次讀取,就會返回緩存的值,不重新計算。
只有當依賴的值變化后,ng才會知道更新緩存的值了
<p>我銀行賬戶的存款:{{money()}}</p>
<p>需要換銀行的貸款:{{payload()}}</p><button (click)="handleChangeAge()">改變存款</button>
money = signal(100);
payload = computed(() => this.money() * 2);
-
計算屬性是不可寫的,也就是無法直接改變,要改變計算屬性最直接的就是改變他依賴的值。
-
直接set是會報錯
副作用effect的使用
就是當任何signal變化時,都會觸發effect的運行,所以我們可以用effect創建一個副作用:
effect(() => {console.log(`The current count is: ${count()}`);
});
在ts項目中,直接這樣寫會提示語法錯誤,需要有返回值。
所以給它賦值下就可以了
或者是在constructor中進行初始化
-
副作用effect使用推薦的場景
- 記錄正在顯示的數據及其更改時間,用于分析或作為調試工具。
- 使數據與 window.localStorage 保持同步。
- 添加無法用模板語法表達的自定義 DOM 行為。
- 對 、圖表庫或其他第三方 UI 庫執行自定義渲染。
-
手動注入effect
import {Component,signal,computed,effect,inject,Injector,
} from '@angular/core';@Component({selector: 'UserProfile',templateUrl: './index.html',styleUrls: ['./index.css'],
})
export class UserProfile {// constructor() {// effect(() => {// console.log(`payload, ${this.payload()}`);// console.log('money-------', this.money());// });// }ngOnInit(): void {this.initializeLogging();}title = '用戶信息展示組件';userInfo = {name: '張三',age: 20,sex: '男',address: {city: '北京',street: '朝陽區',},};readonly money = signal(100);private injector = inject(Injector);payload = computed(() => this.money() * 2);handleChangeAge = () => {this.money.update((v) => v + 100);};initializeLogging(): void {effect(() => {console.log(`The count is: ${this.money()}`);},{ injector: this.injector });}reset(): void {this.money.set(0);}
}
<button (click)="handleChangeAge()">改變存款</button>
<button (click)="reset()">重置</button>
- effect取消對某個值的監聽
untracked
這個api包裹就可以了
effect(() => {console.log(`The count is: ${untracked(this.money)}`);},{ injector: this.injector }
);
- 在effect里面銷毀定時器等操作
effect(
(onCleanup) => {const timer = setInterval(() => {this.money.update((v) => v + 1);}, 1000);onCleanup(() => clearInterval(timer));
},
{ injector: this.injector }
);
}