I have a simple code in Angular 18 as to understand the change mechanismus: By the timeintervall the signal A() value will changed and triggert the computed W. The W reference will be pass to signal E. In the result, E will be updated within the same div and only if W is visiable.
app.component.ts:
import {Component, computed, signal} from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterLink, RouterOutlet],
templateUrl: './app.component.html',
styleUrl: './app.component.scss'
})
export class AppComponent {
title = 'AngularTestV18';
public T: boolean=true
public A=signal(0);
public W = computed(this.A);
E=signal(this.W)
private i=1
private t=setInterval(() => {this.A.set((this.i++));
console.log(this.W());
}, 100);
}
and app.component.html
<div>
App-Template!
<br>
<button (click)="T=!T">W visible</button>
<br>
<div>
<div>
Injected W: {{W()}}
Signal E: {{E()}}
@if (T) { Signal E: {{E()}} }
</div>
<div>
@if (T) { Injected W: {{W()}} }
Signal E: {{E()}}
</div>
</div>
</div>
Why is there a differ between the update strategy of signal E as
App-Template! W/E visible Injected W: 337 Signal E: [Computed: 337] Signal E: [Computed: 109] - updated if W visiable Injected W: 337 Signal E: [Computed: 0] - never updated
?
You should define signal E
as a computed(this.W)
since the computed will trigger to changes of signal W
. In your question E
signal was defined as a signal of a signal (E=signal(this.W)
), which does not work, since signal E
is calculated by W
, so it's a computed
signal.
Even though we remove the signal W
from the DOM/HTML, it does not mean the signal will not trigger the change detection, it will fire for all signals linked to W
.
import { Component, signal, computed } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
@Component({
selector: 'app-root',
standalone: true,
template: `
<div>
App-Template!
<br>
<button (click)="T=!T">W visible</button>
<br>
<div>
<div>
Injected W: {{W()}}
Signal E: {{E()}}
@if (T) { Signal E: {{E()}} }
</div>
<div>
@if (T) { Injected W: {{W()}} }
Signal E: {{E()}}
</div>
</div>
</div>
`,
})
export class App {
title = 'AngularTestV18';
public T: boolean = true;
public A = signal(0);
public W = computed(this.A);
E = computed(this.W);
private i = 1;
private t = setInterval(() => {
this.A.set(this.i++);
console.log(this.W());
}, 100);
}
bootstrapApplication(App);