我有以下容器组件
export class EventsComponent {
data$: Observable<Data[]> = this.store.select(data);
loading$: Observable<boolean> = this.store.select(loading);
}
并通过 | async
将 observable 绑定到展示组件:
<app-presentational
[rowData]="data$ | async"
[loading]="loading$ | async"
...
export class PresentComponent {
@Input()
rowData: Data[];
@Input()
loading: boolean;
}
然而,TS 编译器总是抱怨异步管道可能返回 null。
更新,这是我得到的确切错误
Type 'boolean | null' is not assignable to type 'boolean'.
Type 'null' is not assignable to type 'boolean'.ngtsc(2322)
那么我真的需要将我所有的 @Input()
都改成这个吗?
export class PresentComponent {
@Input()
rowData: Data[] | null;
@Input()
loading: boolean | null;
}
答案 0 :(得分:0)
仅凭您提供的信息我无法判断,但是当 Observable 未提供值时,组件看起来只需要空处理
<app-presentational
[rowData]="data$ | async"
[loading]="(loading$ | async) || false"
/>
答案 1 :(得分:0)
Angular 文档指出 here:
<块引用>上述问题有两种可能的解决方法:
在模板中,包含非空断言运算符!在末尾
可以为空的表达式,例如
在这个例子中,编译器忽略了类型不兼容
可空性,就像在 TypeScript 代码中一样。在异步的情况下
管道,注意表达式需要用括号括起来,如
在
完全禁用 Angular 模板中的严格空检查。
当启用strictTemplates时,仍然可以禁用 类型检查的某些方面。设置选项 strictNullInputTypes 到 false 禁用严格的空检查 角度模板。此标志适用于属于部分的所有组件 应用程序。
但是,您可以:
??
) - 在 Angular 12+ 中可用:TS:
@Component({
template: ``,
})
export class PresentationalComponent {
@Input() loading: boolean;
@Input() rowData: Data[];
}
HTML:
<app-presentational
[loading]="(loading$ | async) ?? false"
[rowData]="(rowData$ | async) ?? []"
></app-presentational>
ngAcceptInputType_*
:TS:
@Component({
template: ``,
})
export class PresentationalComponent {
static ngAcceptInputType_loading?: boolean | null;
// Note that if you have `@angular/cdk` installed you can use this instead:
// static ngAcceptInputType_loading: BooleanInput;
static ngAcceptInputType_rowData?: Data[] | null;
@Input() loading: boolean;
@Input() rowData: Data[];
}
HTML:
<app-presentational
[rowData]="rowData$ | async"
[loading]="loading$ | async"
></app-presentational>
答案 2 :(得分:0)
修改您的代码片段,如下所示。应该修复空分配错误。
<app-presentational
[rowData]="(data$ | async)!"
[loading]="(loading$ | async)!"
...
答案 3 :(得分:-1)
您的 Store State 初始值未定义,这就是您获得 null 或未声明 Store State 对象的原因
export class PresentComponent {
@Input()
rowData: Data[] = [];
@Input()
loading = false;
同样,对于 .select,您正在选择它处理字符串的部分状态: 尝试将它们转换为字符串
export class EventsComponent {
data$: Observable<Data[]> = this.store.select('data');
loading$: Observable<boolean> = this.store.select('loading');
你也可以在进入 state 中的对象时使用多个。
this.store.select('name1', 'name2', ...)
export class EventsComponent implements OnInit {
data: Data[] = [];
loading = false;
constructor(private store: Store<{ data: Data[], loading: boolean}>) {
}
ngOnInit(): void {
// you can do one by one
this.store.select('data')
.subscribe(next => this.data = next);
this.store.select('loading')
.subscribe(next => this.loading = next);
// or do
// all together
this.store.subscribe(next => {
this.data = next.data;
this.loading = next.loading;
});
}
}