【问题标题】:Angular BehaviorSubject undefined at initializedAngular BehaviorSubject 在初始化时未定义
【发布时间】:2022-08-01 22:07:28
【问题描述】:

我正在尝试在服务中创建一个 ICar 类型(由我定义)的新 BehaviorSubject,并默认放置 nullundefined。如果我将类型更新为ICar | undefined,我将在函数getCar() 处收到错误,因为它在抱怨返回类型。是否有任何解决方法来解决此问题?

我的代码:

export interface ICar{
 id:number,
 name: string,
}
//service:
@Injectable({
    providedIn: \'root\'
})
export class CarService {
    private car$ = new BehaviorSubject<ICar>(null); //error

    constructor() {
    }

    setCar(car: ICar) {
        this.car$.next(car);
    }

    getCar(): Observable<ICar> {
        return this.car$;
    }
}
  • 如果您在 tsconfig 中有严格的输入(我认为这是默认打开的),您必须将类型声明为 ICar | null,类似于 new BehaviorSubjec&lt;ICar | null&gt;(null)
  • 是的,但这迫使我将 getCar 的返回类型调整为 BehaviorSubject<ICar | null> 我不想要这个。
  • 你可以创建一个默认的 ICar
  • 如果您不想初始化该值,可以考虑使用SubjectBehaviorSubjectReplaySubject 需要使用值进行初始化。
  • 是什么行为你要的那个?创建BehaviorSubject 建议它应该立即地发出一个值,您传递的默认值(当前为null,这实际上意味着您的主题接收到ICarnull)。如果你想总是发出ICar,默认值需要实现该接口,或者您不应该拥有该默认值(因此不是需要一个的主题)。

标签: angular typescript rxjs


【解决方案1】:

如果您的 car$ 只能在开头为空,并且您只需要 behaviorSubject 来存储先前加载的值,则可以使用类似的东西:

private carSubject = new BehaviorSubject<ICar>(null);
private car$ = carSubject.pipe(filter(car => !!car) car is ICar);

在此过滤器运算符中,您将过滤所有无效值,然后说car 的类型为ICar

而且,就像一个要考虑的建议:也许对这项服务进行一个小的重写会更好。例如,您可以防止从外部更改主题的值(当前实现将从服务传递对主题的引用)。

也许是这样的:

class CarService implements OnDestroy {
  private readonly car = new BehaviorSubject<ICar | null>(null);

  // from the property below you can get your subject values but as 
  // an observable, so it will be closed for .next from outside
  readonly car$ = car.pipe(filter(car => !!car) car is ICar);

  ngOnDestroy(): void {
    this.car.complete(); // <- do not forget to close your subject;
  }

  setCar(car: ICar): void {
    this.car.next(car);
  }
}

【讨论】:

    【解决方案2】:

    如果您打开tsoconfig.ts,您可以添加属性"strictNullChecks": false,。虽然我不知道这样做是否明智。

    https://www.typescriptlang.org/tsconfig#strictNullChecks

    真正的解决方案是简单地说值/类型可以为空,ICar | null

    或者

    您可以使用 Subject 而不是 BehaviorSubject 并仅将有效的 ICar 发布到该流

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-26
      • 1970-01-01
      • 2019-01-09
      • 1970-01-01
      • 2020-08-07
      • 2015-11-12
      • 2015-09-15
      • 1970-01-01
      相关资源
      最近更新 更多