我正在尝试订阅由父组件设置的BehaviourSubject
并将其放入子组件中,我试图在我的组件中添加以下内容:
export class ModuliComponent implements OnInit {
public profilo: Profilo;
constructor(public profiloService: ProfiloService) { }
ngOnInit(): void {
this.profiloService.dataProfilo.subscribe(data => this.profilo = data); // setting profilo
}
}
但是当我尝试在HTML中使用profilo
时,我只是在undefined
或其他* ngIf
asporto
我做错了什么?我应该首先初始化profilo
吗?即使是这样,即使设置onInit
或在constructor
中,profilo = new Profilo();
也会得到未定义的错误...
如果我将console.log设置为订阅,它将返回正确的数据,因此asporto和订阅中的其他内容并不是未定义的。
此处要求提供ProfiloService
@Injectable({
providedIn: 'root'
})
export class ProfiloService {
public dataProfilo = new BehaviorSubject<any>([]);
constructor(private http: HttpClient, private adapter: ProfiloAdapter) { }
profilo(idNegozio: string): Observable<Profilo>{
return this.http
.get(`${Globals.API_URL}/profilo/${idNegozio}`)
.pipe(map((data: any) => this.adapter.adapt(data)));
}
}
这是我要设置dataProfilo的组件:
this.profiloService.dataProfilo.next(profilo);
控制台。从订阅数据登录
编辑:
如果我在父div *ngIf="profilo.moduli"
上添加它可以正常工作,但是此时profilo是未定义的,为什么为什么做一个简单的 *ngIf="profilo"
还不够?
答案 0 :(得分:1)
在html中使用?运算符
<div *ngIf="profilo?.moduli?.ticketing" ></div>
答案 1 :(得分:1)
如果默认情况下将有一个空数组,并检查模板中是否未定义该数组,则建议您将ReplaySubject
与缓冲区1结合使用。它类似于BehaviorSubject
,但不需要默认值。
@Injectable({
providedIn: 'root'
})
export class ProfiloService {
public dataProfilo = new ReplaySubject<any>(1);
constructor(private http: HttpClient, private adapter: ProfiloAdapter) { }
profilo(idNegozio: string): Observable<Profilo>{
return this.http
.get(`${Globals.API_URL}/profilo/${idNegozio}`)
.pipe(map((data: any) => this.adapter.adapt(data)));
}
}
此外,如果仅在控制器中预订可观察对象以仅在模板中直接使用它,则最好使用async
管道。至少,它可以解决退订问题。
子组件
export class ModuliComponent implements OnInit {
public profilo$: Observable<any>;
constructor(public profiloService: ProfiloService) { }
ngOnInit(): void {
this.profilo$ = this.profiloService.dataProfilo;
}
}
模板
<ng-container *ngIf="(profilo$ | async) as profilo">
<section>
...
</section>
</ng-container>
<section>
标记内的模板不必更改,因为我们使用*ngIf
指令的as
签名来表示可观察对象的当前值。
答案 2 :(得分:0)
当初始化子组件时,profilo var是未定义的,并且当API返回数据时,profilo var仅具有数据。因此,您可以使用“?”操作员,或按如下所示检查profilo变量。
<div *ngIf="profilo?.moduli?.ticketing" ></div>
OR
<div *ngIf="profile && profile.moduli && profile.profile.ticketing" ></div>