English 中文(简体)
当信号输入变化时更新模型值
原标题:Update model value when signal input changes
Goal: I want to reset the activeIndex when the message input changes. It doesn t seem appropriate to use a computed signal because the value isn t solely calculated from the input. Possible solutions: Set allowSignalWrites: true in the effect and write the value. In the effect, write the signal value in an untracked block. Both of these seem like they are sub-optimal. Stackblitz Code: interface Message { readonly id: number; readonly contentA: string; readonly contentB: string; } @Component({ selector: app-child , standalone: true, template: `
{{ activeIndex() === 0 ? message().contentA : message().contentB }}
`, }) export class ChildComponent { readonly message = input.required(); // Can t pass equality check for input? readonly computedMessage = computed(() => this.message(), { equal: (a, b) => a.id === b.id, }); // Assume activeIndex is hooked up to some tab control readonly activeIndex = model(0); constructor() { effect(() => { const message = this.computedMessage(); // Want to reset activeIndex when a new message is passed // this.activeIndex.set(0); }); } setTab(index: number) { this.activeIndex.set(index); } } let count = 0; const getNextMessage = (): Message => { ++count; return { id: count, contentA: `MessageA-${count}`, contentB: `MessageB-${count}`, }; }; @Component({ selector: app-root , standalone: true, template: `
`, imports: [ChildComponent], }) export class PlaygroundComponent { readonly message = signal(getNextMessage()); loadNext() { this.message.set(getNextMessage()); } }
问题回答
Convert the input to an observable using toObservable, so that you can listen for changes. Then we trigger the reset logic. Also the extra compute is not needed instead you can go for distinctUntilKeyChanged ... export class ChildComponent { readonly message = input.required(); activeIndex$ = toObservable(this.message).pipe( distinctUntilKeyChanged( id ), map(() => { this.activeIndex.set(0); return this.activeIndex(); }) ); // Assume activeIndex is hooked up to some tab control readonly activeIndex = model(0); constructor() { this.activeIndex$.subscribe(); } setTab(index: number) { this.activeIndex.set(index); } } ... Full Code: import { Component, computed, effect, input, model, signal, } from @angular/core ; import { bootstrapApplication } from @angular/platform-browser ; import { toObservable } from @angular/core/rxjs-interop ; import { CommonModule } from @angular/common ; import { map, distinctUntilKeyChanged } from rxjs ; interface Message { readonly id: number; readonly contentA: string; readonly contentB: string; } @Component({ selector: app-child , standalone: true, imports: [CommonModule], template: `
{{ activeIndex() === 0 ? message().contentA : message().contentB }}
`, }) export class ChildComponent { readonly message = input.required(); activeIndex$ = toObservable(this.message).pipe( distinctUntilKeyChanged( id ), map(() => { this.activeIndex.set(0); return this.activeIndex(); }) ); // Assume activeIndex is hooked up to some tab control readonly activeIndex = model(0); constructor() { this.activeIndex$.subscribe(); } setTab(index: number) { this.activeIndex.set(index); } } let count = 0; const getNextMessage = (): Message => { ++count; return { id: count, contentA: `MessageA-${count}`, contentB: `MessageB-${count}`, }; }; @Component({ selector: app-root , standalone: true, template: `
`, imports: [ChildComponent], }) export class PlaygroundComponent { readonly message = signal(getNextMessage()); loadNext() { this.message.set(getNextMessage()); } } bootstrapApplication(PlaygroundComponent); Stackblitz Demo




相关问题
Angular matSort not working on Date column by desc

Trying to sort the material table with date column , date format is MM/DD/YYYY ,h:mm A , order of date is not by latest date and time. Anything which i missed from the below stackblitz code. https:/...

热门标签