Angular 4中如何在组件事件触发时调用另一个Loader组件
如何在LangComponent中调用Loader组件?
问题背景
我有一个LoaderComponent,它通过订阅LoaderService的状态来控制显示隐藏。现在我想在LangComponent的语言切换回调中触发这个Loader的显示,请问该怎么做?
现有代码
loader.component.ts
export class LoaderComponent implements OnInit { show = false; private subscription: Subscription; constructor(private loaderService: LoaderService) { } ngOnInit() { this.subscription = this.loaderService.loaderState.subscribe( (state: LoaderState) => { if (state.queue.length > 0) { this.show = true; } else { this.show = false; } }); } ngOnDestroy() { /// 这里需要补充取消订阅的代码 } }
lang.component.ts
ngOnInit(): void { //// this.translate.onLangChange.subscribe((event: LangChangeEvent) => { if(event.lang){ console.log(event.lang) // 我希望在此处调用Loader组件 } }); }
LoaderService.ts
@Injectable() export class LoaderService { private loaderSubject = new Subject<LoaderState>(); loaderState = this.loaderSubject.asObservable(); private loaderQueue = new LoaderState(); constructor() { } add() { this.loaderQueue.queue.push(true); this.loaderSubject.next(this.loaderQueue); } pop() { this.loaderQueue.queue.pop(); this.loaderSubject.next(this.loaderQueue); } }
解决方案
你不能直接在LangComponent中调用LoaderComponent实例,因为组件的显示逻辑已经通过LoaderService解耦了。正确的做法是通过LoaderService来发送状态指令,让LoaderComponent自动响应变化。具体步骤如下:
1. 先完善LoaderComponent的内存泄漏防护
在LoaderComponent的ngOnDestroy中取消订阅,避免内存泄漏:
ngOnDestroy() { if (this.subscription) { this.subscription.unsubscribe(); } }
2. 在LangComponent中注入LoaderService
首先在LangComponent的构造函数中注入LoaderService:
// 先导入LoaderService import { LoaderService } from './path/to/loader.service'; export class LangComponent implements OnInit, OnDestroy { // 记得添加必要的导入(OnInit, OnDestroy等) private langSubscription?: Subscription; constructor( private translate: TranslateService, private loaderService: LoaderService // 注入LoaderService ) { } // ... 其他代码 }
3. 在语言切换回调中控制Loader状态
如果语言切换是异步操作(比如从服务器加载语言包),你需要在操作开始时调用add()显示Loader,操作完成后调用pop()隐藏Loader。示例如下:
ngOnInit(): void { this.langSubscription = this.translate.onLangChange.subscribe(async (event: LangChangeEvent) => { if(event.lang){ console.log(event.lang); // 显示Loader this.loaderService.add(); try { // 假设这里有异步操作,比如加载语言相关的资源 await this.loadLangRelatedResources(event.lang); } finally { // 无论成功失败,都隐藏Loader this.loaderService.pop(); } } }); } // 示例异步方法 private async loadLangRelatedResources(lang: string): Promise<void> { // 模拟异步请求,比如调用API加载语言配置 return new Promise(resolve => setTimeout(resolve, 1000)); } // 别忘了取消订阅langChange ngOnDestroy() { if (this.langSubscription) { this.langSubscription.unsubscribe(); } }
如果语言切换是同步操作,你可以短暂显示Loader(比如模拟加载效果):
ngOnInit(): void { this.langSubscription = this.translate.onLangChange.subscribe((event: LangChangeEvent) => { if(event.lang){ console.log(event.lang); this.loaderService.add(); // 短暂显示后隐藏 setTimeout(() => { this.loaderService.pop(); }, 500); } }); }
4. 确保LoaderComponent在应用中已渲染
最后,要确保LoaderComponent已经在你的应用模板中(比如全局的app.component.html),这样它才能接收到Service的状态变化:
<!-- app.component.html --> <app-loader></app-loader> <!-- 其他组件内容 -->
内容的提问来源于stack exchange,提问作者aulona aulona
相关产品推荐
相关产品推荐

