计算讯号快取错误
计算讯号中的错误快取是 Angular 19.1.2 中的新功能。当 equal 函数抛出错误时,计算讯号会快取该错误。当读取该值时,计算讯号会抛出错误,从而停止 computed 和 equal 函数的重新运行。
HTML 模板显示计算讯号的最后一个成功值,直到错误清除。当 computed 函数和 equal 函数重新运行时没有错误,计算讯号将清除错误。
由于计算讯号会抛出快取错误,因此依赖它的讯号直到错误清除后才会更新。
badLuck = signal(0);
numBadNumberRun = 0;
numBadNumberEqualRun = 0;
badLuckComputed = computed (() => {
this.numBadNumberRun = this.numBadNumberRun + 1;
return this.badLuck();
}, {
equal: (_, b) => {
this.numBadNumberEqualRun = this.numBadNumberEqualRun + 1;
if ([4, 14, 24, 44].includes(b)) {
throw new Error("Bad number thrown");
}
return false;
}});
incrementBadLuck() {
this.badLuck.update((prev) => prev + 1);
}
<p>Bad Luck computed: {{ badLuckComputed() }}, Number of executions: {{ numBadNumberRun }}, Number of equal executions: {{ numBadNumberEqualRun }}</p>
<hr />
badLuck 是一个储存整数的讯号。当使用者点击按钮时,讯号增加1。 badLuckComputed 是一个传回 badLuck 值的计算讯号。当 badLuck 不幸时,equal 函数会抛出错误,并且 badLuckComputed 计算讯号会将其快取。例如,badLuckComputed 在 badLuck 为 4 时快取错误,HTML 模板显示 badLuck(4)和 badLuckComputed(3)。 当使用者点击按钮时,badLuck 变成 5,equal 函数传回 false 而不是错误。 badLuckComputed 的错误被清除,并且 badLuck 和 badLuckComputed 都显示 5。
sumOfLuck = computed(() => this.badLuckComputed() + this.count())
sumOfLuck 是计算讯号,等于 badLuckComputed 和 count 讯号的总和。 当任何一个讯号改变时,sumOfLuck 计算讯号会得到一个新值,除非 badLuckComputed 讯号快取了错误。
当 sumOfLuck 的计算函数运行时,badLuckComputed 计算讯号会抛出错误,且讯号不会更新。 当 count 讯号更新时也会发生同样的事情。 sumOfLuck 的 computed 函数评估 badLuckComputed,并抛出错误。因此,sumOfLuck 计算讯号不会更新。
当 badLuckComputed 计算讯号更新时,它会清除错误。 sumOfLuck 的 computed 函数运行并评估 badLuckComputed 和 count 讯号。 函数在执行时间没有错误,且 sumOfLuck 计算讯号储存新的总数。
Equal 函数不追踪讯号
equal 函数不追踪讯号。假设组件其他部分修改讯号值;computed 和 equal 函数不会重新运行。 当追踪的讯号导致 computed 和 equal 函数重新运行时,新的讯号值有效。
此示范计算原始文字和新文字之间的相似度得分。当两个文字相似时,upperSimilarText 的计算讯号会以大写形式显示新文字。 equal 函数呼叫 javascript 函式库来计算分数并与 minSimilaryScore 讯号进行比较。 使用者点击按钮可以将 minSimilarityScore 减少或增加 0.05。当 minSimilarityScore 讯号透过按钮点选更新时,upperSimilarText 计算讯号不会重新运作。
安装 dependency
npm install string-similarity-js
安装 string-similarity-js 比较两个字串并传回相似度分数。
getSimilarScore(b: string) {
return stringSimilarity(this.originalText, b);
}
minSimilarityScore = signal(0.5);
readonly originalText = \'The quick brown fox jumps over the lazy dog\';
readonly delta = 0.05;
text = signal(this.originalText);
score = computed(() => this.getSimilarScore(this.text()));
<div>
<input style="width: 100%;" [(ngModel)]="text" />
</div>
<div>score: {{ score() }}</div>
模板有一个输入字段,新文字储存在 text 讯号,并将相似度分数储存在 score 计算讯号中。。
modify(amount: number) {
this.minSimilarityScore.update((prev) => Math.max(0, Math.min(1, prev + amount)));
}
<button (click)="modify(-delta)">Reduce the minimum similarity score by {{ delta }}</button>
<button (click)="modify(delta)">Add the minimum similarity score by {{ delta }}</button>
当使用者点击按钮时,minSimilarityScore 讯号会增加或减少0.05。
upperSimilarText = computed(() => {
this.numComputedRun = this.numComputedRun + 1;
return this.text().toUpperCase();
}, {
equal: (_, b) => {
this.numEqualRun = this.numEqualRun + 1;
this.getSimilarScore(b) < this.minSimilarityScore();
}});
<div>
<p>{{ upperSimilarText() }}</p>
<p>numComputedRun: {{ numComputedRun }}, numEqualRun: {{ numEqualRun }}</p>
</div>
当使用者在文字方块中输入新文字时,score 的 computed 函数会重新运行以计算新的相似度分数。当相似度分数小于 minSimilarityScore 的值时,upperSimilarText 的 computed 函数也会重新运行并更新。
当使用者点击按钮来改变 minSimilarityScore 的值时,upperSimilarText 不会重新运行,因为其 equal 函数不会追踪讯号。当使用者在文字方块中输入新文字时,upperSimilarText 计算讯号会重新运行并在 equal 函数中使用 minSimilarityScore 讯号的新值。
以上就是我对计算讯号的错误快取与 equal 函数中追踪讯号的分享。
参考:
- PR: https://github.com/angular/angular/pull/55818
- Stackblitz Demo: