Я пытаюсь использовать новые toSignal
и input
с новым angular 17.x. Но когда дело доходит до «ввода», я могу получить только значение «OnInit», как я могу решить эту проблему, потому что я пытаюсь отфильтровать наблюдаемое с помощью входящего значения из декларативного ввода.
Надеюсь, вы, ребята, понимаете, что я имею в виду.
transferId = input.required<string>();
progressSteamType = input.required<string>();
progressBarHeightSmall = input<boolean>(true);
progress$ = this._progressService.progress$;
private _subs = new Subscription();
progress = toSignal<IProgress | null>(this.progress$);
ngOnInit(): void {
this.progress$.pipe(
filter(p => p.transferId.toLowerCase() === this.transferId()?.toLowerCase() && p.type === this.progressSteamType()) <--- this won't work because i already declared it above. The only way i can get the transferId is in ngOnit. because its an input
)
}
Я хочу добиться чего-то вроде этого. Но это не сработает. потому что TransferId не инициировался
progress$ = this._progressService.progress$.pipe(
filter(p => p.transferId.toLowerCase() === this.transferId()?.toLowerCase() && p.type === this.progressSteamType())
)
Мы можем использовать effect
, чтобы отслеживать новые изменения сигнала и запускать обновление канала! Только когда TransferId доступен, мы запускаем обновление!
Затем мы берем effectRef
, который можно использовать для уничтожения сигнала, как только мы закончим обновление канала. Для этого мы можем использовать effectRef.destroy()
!
import { Component, effect, input } from '@angular/core';
import { Subscription, of, interval } from 'rxjs';
import { toSignal } from '@angular/core/rxjs-interop';
import { filter, map } from 'rxjs/operators';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-child',
standalone: true,
imports: [CommonModule],
template: `{{progress$ | async | json}}`,
})
export class ChildComponent {
transferId = input.required<string>();
progressSteamType = input.required<string>();
progressBarHeightSmall = input<boolean>(true);
progress$ = interval(1000).pipe(
map(() => ({ transferId: 'test', type: 'qwerty' }))
);
private _subs = new Subscription();
progress = toSignal<any | null>(this.progress$);
constructor() {
const effectRef = effect(() => {
const transferId = this.transferId();
if (transferId) {
console.info('time to cleanup', transferId, this.progressSteamType());
this.progress$ = this.progress$.pipe(
filter(
(p: any) =>
p.transferId.toLowerCase() === transferId?.toLowerCase() &&
p.type === this.progressSteamType()
)
);
effectRef.destroy();
}
});
}
ngOnInit(): void {}
}
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { ChildComponent } from './app/child/child.component';
@Component({
selector: 'app-root',
imports: [ChildComponent],
standalone: true,
template: `
<app-child [transferId] = "'test'" [progressSteamType] = "'qwerty'"/>
`,
})
export class App {}
bootstrapApplication(App);
@Tan, не могли бы вы воспроизвести проблему в опубликованном стеке и сообщить мне, что не так, я проверю это!
Спасибо за помощь. Я не могу воспроизвести это в stackblitz. Так что это должно быть где-то еще в моем коде.
Это вроде как работает, но когда я создал больше экземпляров дочерних компонентов, они получили те же значения. Я думаю, что this.progress$ = this.progress$.pipe( filter( (p: Any) => p.transferId.toLowerCase() === TransferId?.toLowerCase() && p.type === this.progressSteamType( ) ) ); эта часть не работает. toSignal, кажется, не обновляется