我正在尝试将数据从 Angular 17 中的父组件传递到其子组件。 通过获取项目数组的 API 从后端检索数据。
在我的父组件中,items$ 是一个主题:
items$ = Subject<Array<Item>> = new Subject();
我订阅了从后端检索所有项目的服务方法:
ngOnInit(){
this.itemService.getItems().subscribe(this.items$);
}
在我的 parent.html 模板中,此代码确实显示有项目:
@if(items$ | async){
"There are items!"
}@else{
"There aren't any items"
}
然后我调用我的子组件:
@if(items$ | async){
<app-child [items$]=items$>
}
这就是我的 child.component.ts 的样子:
export class ChildComponent implements OnInit{
@Input() items$: Observable<Array<Item>>;
ngOnInit(){
this.items$.subscribe();
}
}
一个 child.component.html:
@if(items$ | async){
"There are items in the child component!"
}@else{
"There aren't any items in the child component"
}
嗯,它显示子组件中没有任何项目。
我知道我不需要订阅子组件的 onInit() 方法,但我真的只是想确保我确实订阅了我的多播可观察对象。
此外,有趣的是,当我将子组件从 parent.html 中的 @if 条件中取出时,项目正在显示!
知道为什么吗?如何根据项目的存在来调节子组件的显示?
您可以将
Subject
转换为 BehaviorSubject
,以便它保持状态(数组)。当您想要触发不保持状态的事件(事件总线)的发射时,首选主题。
您还应该在订阅中编写一个回调,使用 API 中的数据调用
next
的 BehaviorSubject
方法。
itemService = inject(ItemService);
items$: BehaviorSubject<Array<any> | null> =
new BehaviorSubject<Array<any> | null>(null);
ngOnInit() {
this.itemService.getItems().subscribe((data: any) => {
this.items$.next(data);
});
}
import { Component, inject, Injectable, Input, OnInit } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { Observable, of, Subject, BehaviorSubject } from 'rxjs';
import { CommonModule } from '@angular/common';
@Injectable({ providedIn: 'root' })
export class ItemService {
getItems() {
return of([{ test: 1 }]);
}
}
@Component({
selector: 'app-child',
imports: [CommonModule],
template: `
@if(items$ | async) {
"There are items in the child component!"
} @else {
"There aren't any items in the child component"
}
`,
})
export class ChildComponent implements OnInit {
@Input() items$!: Observable<Array<any> | null>;
ngOnInit() {
this.items$.subscribe();
}
}
@Component({
selector: 'app-root',
imports: [CommonModule, ChildComponent],
template: `
@if(items$ | async){
"There are items!"
}@else{
"There aren't any items"
}
<hr/>
@if(items$ | async) {
<app-child [items$]="items$"/>
}
`,
})
export class App {
itemService = inject(ItemService);
items$: BehaviorSubject<Array<any> | null> =
new BehaviorSubject<Array<any> | null>(null);
ngOnInit() {
this.itemService.getItems().subscribe((data: any) => {
this.items$.next(data);
});
}
}
bootstrapApplication(App);