-
我有
popupservice
,它为我打开弹出组件,如下所示:export class PopupService { alert() { this.matdialog.open(PopupAlertComponent); } yesno() { this.matdialog.open(PopupYesNoComponent); } custom() { this.matdialog.open(PopupCustomComponent); } }
-
然后我用
this.popupservice.custom()
打开我的自定义弹出窗口。export class HomeComponent { constructor(private popupservice: PopupService) {} openCustomPopup() { this.popupservice.custom(); } }
-
然后,在我的
custom
弹出组件中,我想调用我自己的alert
弹出(报告错误或其他事情(:export class CustomPopup { constructor(private popupservice: PopupService) {} doHttpCall() { ...do http calls... if (callFailed) this.popupservice.alert('Call Failed'); } }
如何解决这个循环依赖问题
注意:
- 我已经阅读了其他问题,但我觉得我的问题是一个特定的"帮助我"问题。尽管仍然欢迎您向我介绍其他问题
this.popupservice.alert()
不仅仅是一个javascriptalert
,它是我自己的自定义弹出窗口,有一个主题和所有内容
您可以做的是从PopupService
中删除弹出创建逻辑。这里有一个小重构。
使用PopupService
只能从应用程序的不同部分创建事件。
@Injectable()
export class PopupService {
private _alert: Subject<any> = new Subject();
private _yesno: Subject<any> = new Subject();
private _custom: Subject<any> = new Subject();
// since you didn't like the on- methods, you can do following
public readonly alert$ = this._alert.asObservable();
public readonly yesno$ = this._yesno.asObservable();
public readonly custom$ = this._custom.asObservable();
onAlert() { return this._alert.asObservable(); }
onYesno() { return this._yesno.asObservable(); }
onCustom() { return this._custom.asObservable(); }
alert(payload) { this._alert.next(payload); }
yesno(payload) { this._yesno.next(payload); }
custom(payload) { this._custom.next(payload); }
}
因此,我们有一个PopupService
,它只发出一些带有一些payload
s的事件。我在这里使用了Subject
,因为以后的订阅者不需要知道之前是否有alert
或yesno
事件。如果您想拥有这样的逻辑,可以将Subject
更改为BehaviorSubject
。
创建一个名为PopupManager
的组件并在app.component
中使用
app.component.ts
@Component({
selector: 'app-root',
template: `
<!-- some template -->
<app-popup-manager></app-popup-manager>
`
})
export class AppComponent {}
@Component({
selector: 'app-popup-manager',
template: '' // don't need to have template
})
export class PopupManagerComponent implements OnInit {
constructor(private matDialog: MatDialog, private popupService: PopupService) {}
ngOnInit() {
this.popupService.onAlert().subscribe(payload => {
// this.matDialog.open...
});
this.popupService.onYesno().subscribe(payload => {
// this.matDialog.open...
});
this.popupService.onCustom().subscribe(payload => {
// this.matDialog.open...
});
}
}
通过这种方式,您可以在任何需要的组件中使用PopupService,因为它现在是一个单独的、独立的服务。
为什么不应该向外界公开Subject
您可以考虑这样封装类字段。你们确实可以将_alert
暴露在外部世界,但那个么你们将无法控制谁以何种方式使用这个主题。方法总是提供功能的好方法,同时保持对字段的一些控制。将来,您可能想要更改服务的内部,也许是某些主题。如果让应用程序的其他部分直接访问字段,则需要进行大量重构。但通过这种方式,既然你给了他们一些方法,只要你不破坏这些方法,你就会没事的。
您的服务不应该了解组件,如果您的服务了解组件,那就是糟糕的设计。你应该在你的服务中有一个类似行为主题的可观察对象,并让你的组件订阅该可观察对象以知道何时弹出新消息。
在您的服务
message$ = new BehaviourSubject<string>(null);
以及用于沿着流水线发送消息的功能。
nextMessage(message: string) {
this.message$.next(message);
}
然后在你的组件中订阅消息$observable,然后弹出。
this.messageSubscription = this.service.message$.subscribe(message => { this.popup(message); });
确保在ngDestroy上取消订阅或取消订阅。
ngOnDestroy() {
if (this.messageSubscription ) {
this.messageSubscription.unsubscribe();
}
}