如何将信号中的更新值接收到 Angular 路由解析器中?

问题描述 投票:0回答:1

我正在使用 Angular 17 并使用新的 Signals API 来管理应用程序中的状态。我有一个服务,它保存浏览器标题的信号,我想在路由解析器中使用该信号。但是,我面临一个问题,解析器仅获取第一个发出的值,该值为 null 默认值,并且不接收后续更新。

服务:

import { Injectable, signal } from '@angular/core';
import { toObservable } from '@angular/core/rxjs-interop';

@Injectable({ providedIn: 'root' })
export class CommonService {
  public browserTitle = signal<string | null>(null);
  public readonly browserTitle$ = toObservable(this.browserTitle);

  public setBrowserTitle(title: string | null): void {
    this.browserTitle.set(title);
  }
}

详细解析器:

import { inject } from '@angular/core';
import { ToastrService } from 'ngx-toastr';
import { CompanyService } from '../service';
import { CommonService } from '@core/services';
import { ICompanyDetailDataset } from '../models';
import { ResolveFn, Router } from '@angular/router';
import { EMPTY, Observable, catchError, map } from 'rxjs';

export const companyDetailResolver: ResolveFn<Observable<ICompanyDetailDataset>> = (
    route,
    state
) => {
    const companyId = route.params['companyId'];

    const _router = inject(Router);
    const _toastr = inject(ToastrService);
    const _commonService = inject(CommonService);
    const _companyService = inject(CompanyService);

    return _companyService.fetchCompany(companyId).pipe(
        map((companyDetails) => {
            _commonService.setBrowserTitle(companyDetails.name);
            return { company_details: companyDetails };
        }),
        catchError((error: Error) => {
            _toastr.error(error.message);
            _router.navigate(['companies']);
            return EMPTY;
        })
    );
};

标题解析器:

import { Observable, map } from 'rxjs';
import { inject } from '@angular/core';
import { ResolveFn } from '@angular/router';
import { CommonService } from '@core/services';

export const companyUpdateTitleResolver: ResolveFn<string> = (
  route,
  state
) => {
  const _commonService = inject(CommonService);

  return _commonService.browserTitle$.pipe(
    map((title) => {
      return !title ? 'Update Company' : `Update Company: ${title}`;
    })
  );
};
angular typescript angular-signals
1个回答
0
投票

Resolver,通常是一个函数,在组件加载之前执行,我们可以在组件加载之前完成一个可观察的,或布尔值,或API调用,但请注意它不会等待新值,它会立即解析,所以你会得到这种行为。

如果你问我

companyUpdateTitleResolver
绝对是多余的,我们可以在第一个解析器本身上获取标题,我们还可以订阅组件加载时信号的变化!

创建一个返回

computed
标题的新属性

import { Injectable, signal, computed } from '@angular/core';
import { toObservable } from '@angular/core/rxjs-interop';

@Injectable({ providedIn: 'root' })
export class CommonService {
  public browserTitle = signal<string | null>(null);
  public readonly browserTitle$ = toObservable(this.browserTitle);
  public fullTitle = computed(() => {
      const title = this.browserTitle();
      return !title ? 'Update Company' : `Update Company: ${title}`;
  });

  public setBrowserTitle(title: string | null): void {
    this.browserTitle.set(title);
  }
}

然后在组件加载时我们可以使用数据!

@Component({ ... })
export class SomeComponent {
    _commonService = inject(CommonService);
    constructor() {
        effect(() => {
             const newTitle = this._commonService.fullTitle();
             // do something with title!
        });
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.