我有一个应用程序,试图基于服务中的公共变量显示或隐藏元素。像show: boolean = false;
一样实例化了此变量,但是随后从子组件中对其进行设置。
我的问题是show
似乎从未更新过它的值。
在进行各种调试时,我发现show
设置为初始值,但是一旦视图初始化完成,检查器就会显示show
是未定义的,尽管这可能不相关我的问题。
那么如何显示子组件中的父元素?
以下代码:
app.component.html
<div *ngIf="appService.show"> Loading </div>
<div *ngIf="!appService.show"> Content </div>
应用组件
export class AppComponent implements OnInit {
constructor(private appService: AppService) {}
ngOnInit() {}
}
应用服务
export class AppService {
public show: boolean = false;
showLoader() {
this.show = true;
}
hideLoader() {
this.show = false;
}
}
child.component
export class ChildComponent implements OnInit {
constructor(private appService: AppService) {}
// This is just an example, I've got the showLoader() method firing after a subscription completes.
ngOnInit(){
this.appService.showLoader();
}
}
答案 0 :(得分:1)
使显示字段可观察。
应用服务
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AppService {
public show$ = new BehaviorSubject(false);
constructor() { }
showLoader() {
this.show$.next(true);
}
hideLoader() {
this.show$.next(false);
}
}
并在需要收听的地方订阅。
答案 1 :(得分:1)
完成此操作的最佳方法是创建一个可观察的对象来管理加载状态。我更喜欢使用BehaviorSubject
,因为它会记住它发出的最后一个值。您可以让多个组件订阅加载服务。 (有关行为主题here的更多信息)。
这是一个指向stackblitz的链接,在其中我实现了此加载程序服务的简单版本:https://stackblitz.com/edit/angular-loading-service-subscribe
编辑:我将child.component
的代码添加到了答案中。我把它放在堆栈闪电战中,但是忘了在这里添加它。
主要说明:
loading.service.ts
具有BehaviorSubject
,用于管理应用程序是否正在加载数据。它返回自身.asObservable()
,因此没有子组件可以在其上调用.next()
。
export class LoadingService {
private _isLoading$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
get isLoading$(): Observable<boolean> {
return this._isLoading$.asObservable();
}
// see the rest of the code in the stackblitz
}
一旦连接好,就将其注入组件中。
app.component.ts
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// by making it public, you can subscribe in the template
constructor(public loadingService: LoadingService) { }
}
app.component.html
<ng-template [ngIf]="loadingService.isLoading$ | async" [ngIfElse]="loaded">
Loading
</ng-template>
<ng-template #loaded>
Content has loaded
</ng-template>
<!-- see child.component -->
<child></child>
child.component然后可以使用loading.service
控制加载指示器。
@Component({
selector: 'child',
template: `
<h1>Child Component</h1>
<button (click)="toggleLoading()">Change Loading</button>
`,
styles: [`h1 { font-family: Lato; }`]
})
export class ChildComponent {
constructor(public loadingService: LoadingService) { }
// simulates a 3 second load time for fetching data
ngOnInit() {
this.loadingService.startLoading();
setTimeout(() => {
this.loadingService.stopLoading();
}, 3000);
}
// simple method to simulate user action that loads some new data
toggleLoading(): void {
this.loadingService.toggleLoading();
}
}
签出此资源以获取有关ng-template
的信息:https://toddmotto.com/angular-ngif-else-then
,其中一个用于async
管道:https://angular.io/api/common/AsyncPipe