代码之家  ›  专栏  ›  技术社区  ›  Lenni

返回信号并在Angular中订阅它

  •  1
  • Lenni  · 技术社区  · 10 月前

    我现在有这段代码。我使用信号,因为我知道这是实现我想要实现的最新方法,而不是使用observable或toPromise(),后者已被弃用。我也明白,使用 async / await 语法不是解决这个问题的方法。

    entryArray$ = signal<Entry[]>([]);
    
    getEntryBatch(lemma?: string): Entry[] {
        if (lemma) {
          this.httpClient
            .get<Entry[]>(`${this.url}/entries/l/${lemma}`)
            .subscribe((response) => {
              this.entryArray$.set(response);
              console.log(this.entryArray$()) // this logs the expected response
            });
          console.log(this.entryArray$()); // this runs too early
        } else {
          console.log('error catching lemma');
        }
        console.log(this.entryArray$()); // this runs too early
        return this.entryArray$();
      }
    

    当我按如下方式调用函数时,我没有得到预期的响应:

    this.resultEntries$.set(
          this.entriesService.getEntryBatch(this.searchService.mySearch().letter),
        );
    

    我试过改变 .subscribe((res) => ... .pipe(map((res) =>((res) =>... 因为有些帖子建议我在这种情况下应该这样做,但也没能奏效。我的理解是,我需要实现的是功能 getEntryBatch 返回一个信号,然后在调用函数时订阅该信号 getEntryBatch(...).subscribe() 但我无法完成这项工作。

    2 回复  |  直到 10 月前
        1
  •  2
  •   Naren Murali    10 月前

    信号方法:

    尝试使用 effect 以触发数据刷新。

    effect(() => {
        this.entriesService.getEntryBatch(this.searchService.mySearch().letter).subscribe();
    });
    

    然后使用getter访问组件中服务的信号。

    get resultEntries$() {
        return this.entriesService.entryArray$;
    }
    

    然后,您可以将服务重写为。

    entryArray$ = signal<Entry[]>([]);
    
    getEntryBatch(lemma?: string): Observable<Entry[]> {
          return (lemma ? this.httpClient
            .get<Entry[]>(`${this.url}/entries/l/${lemma}`) : of([]))
            .pipe(tap((response) => {
              this.entryArray$.set(response);
            });
      }
    

    可观察方法:

    您可以使用 toObservable 将信号转换为可观测信号,可观测信号将对源信号的变化做出反应

    entryArray$ = toObservable(this.searchService.mySearch()).pipe(
        switchMap((mySearch: any) => this.entriesService.getEntryBatch(mySearch.letter)),
    );
    

    在HTML中,我们可以使用异步管道(来自JSmith答案)

    for( result of entryArray$ | async; track $index ) {
       ...
    }
    
        2
  •  0
  •   Žiga GroÅ¡elj    10 月前

    你可以做这样的事情。toSignal需要一个observable并订阅它,如果不在注入上下文中使用,这意味着在构造函数或顶层,您还需要传递注入器。

    resultEntries$ = toSignal(this.httpClient
        .get<Entry[]>(`${this.url}/entries/l/${lemma}`)) 
    

    对于你来说,你可以将toSignal中的内容移动到一个方法中,并执行类似的操作:

    resultEntries$ = toSignal(getEntryBatch('lemma')) 
    
    getEntryBatch():Observable<Entry[]>{
     // implementation of api call here, without subscribe, you should return observable.
    }