Angular Circular Dependency Solution


  • 我有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,它只发出一些带有一些payloads的事件。我在这里使用了Subject,因为以后的订阅者不需要知道之前是否有alertyesno事件。如果您想拥有这样的逻辑,可以将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();
}
}

相关内容

最新更新