Angular 17 - Как использовать новый ввод с декларативным значением с toSignal

Я пытаюсь использовать новые 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())
  )
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
0
246
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мы можем использовать 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);

Демо-версия Stackblitz

Это вроде как работает, но когда я создал больше экземпляров дочерних компонентов, они получили те же значения. Я думаю, что this.progress$ = this.progress$.pipe( filter( (p: Any) => p.transferId.toLowerCase() === TransferId?.toLowerCase() && p.type === this.progressSteamType( ) ) ); эта часть не работает. toSignal, кажется, не обновляется

Tan 22.05.2024 19:35

@Tan, не могли бы вы воспроизвести проблему в опубликованном стеке и сообщить мне, что не так, я проверю это!

Naren Murali 22.05.2024 19:44

Спасибо за помощь. Я не могу воспроизвести это в stackblitz. Так что это должно быть где-то еще в моем коде.

Tan 23.05.2024 13:38

Другие вопросы по теме

Похожие вопросы