我有一个服务,它使用一个初始化为1的行为主体.该值可以在1和2之间切换,以表示轮到哪个玩家.

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class PlayerTurnService {
  private playerTurnState$ = new BehaviorSubject<number>(1);

  nextPlayerTurn() {
    this.playerTurnState$.next(this.playerTurnState$.value === 1 ? 2 : 1);
  }

  getCurrentPlayerTurn() {
    return this.playerTurnState$.asObservable();
  }
}

我正在使用属性绑定将该值赋给一个组件,该组件只是一个标签,说明哪些玩家轮流.

<app-player-label [currentPlayerTurn]="playerTurn$ | async"></app-player-label>


@Component({
  selector: 'app-player-label',
  template: `
    <p>Player {{playerTurn}} turn </p>
  `,
  standalone: true,
  styles: [],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PlayerTurnLabelComponent {
  
  @Input() playerTurn!: number;
}

但我得到了以下错误.

类型‘Number|Null’不可赋值给类型‘Numbers’.

我可以修复这个错误,但将输入设置为数字或空.

@Input() playerTurn!: number | null;

但这感觉不太对劲.特别是因为我使用了非空的断言操作符来让TypeScrip知道这个值永远不会为空.

关于行为主体如何初始化此值,我是否遗漏了什么?为什么会发生这种事?

出于演示的目的,我已经在Stackblitz中重现了这个问题.

推荐答案

由于async,所以PIPE默认返回空值或未定义的值.

您可以通过在模板上使用类似于此的提供默认值来解决此问题.

<app-player-label [playerTurn]="(playerTurn$ | async) ?? 0"></app-player-label>
<p>{{playerTurn$ | async}}</p>
<button (click)="toggle()">Toggle turn</button>

100

Angular相关问答推荐

如何go 除融合图中的拖尾水印?

如何将管道异步化添加到不在html模板中的观察对象的Angular ?

当嵌套在异步容器中时,S会阻止具有动态值的ionic 段工作吗?

HTTP POST响应失败Angular 16

如何防止打印后的空格后的HTML元素的Angular ?

VS代码中带Angular 17的缩进新控制流

使用 primeng Apollo 主题进行实时部署时多次加载 theme.css 和 preloading.css 文件

从 applescript 调用Angular 前端以从列表中 Select 一个项目

无法使用@ngrx/component-store 在其他组件中获取状态更改值

等待两个订阅完成而不嵌套

如何在 Angular 2 中使用 protractor ?

Angular ngFor 索引从 1 开始 循环

Angularmaterial步进器:禁用标题导航

@angular/platform-b​​rowser 与 @angular/platform-b​​rowser-dynamic

Angular 2 Material Design 组件是否支持布局指令?

得到了预期表达式的插值 ({{}})

错误:angular2 中没有 HttpHandler 的提供者

如何在Angular中使用带有 td 属性 colspan 的属性绑定?

输入更改时Angular2动态输入字段失go 焦点

Angular 4 - 获取输入值