tl; dr: прокрутите вниз до решения
У меня круговая зависимость, и я получаю предупреждение, по праву, однако, я управляю им. Проблема в том, что у меня есть компонент чата. В углу вы можете выбрать, чтобы увидеть страницу их профиля, а на странице их профиля у вас есть возможность отправить им сообщение, отсюда и круговая зависимость. Я управляю этим с помощью
chat.component
public async openProfile(): Promise<void> {
this.modalCtrl.dismiss(); //closing the chat component before opening the profile modal
const profile = await this.modalCtrl.create({
component: ProfileComponent,
});
await profile.present();
}
profile.component
public async openChat(): Promise<void> {
this.modalCtrl.dismiss(); //closing the profile component before opening the chat modal
const chat = await this.modalCtrl.create({
component: ProfileComponent,
});
await chat.present();
}
Есть ли более простой способ обработки этой циклической зависимости?
ОБНОВЛЕНИЕ: согласно предложению ниже я попытался создать сервис. Однако теперь у меня есть трехсторонний круг зависимостей:
chat.component
private modalService: ModalService;
constructor(modalService: ModalService){
this.modalService = modalService
}
public async openProfile(): Promise<void> {
this.modalService.openProfile(this.userData);
}
profile.component
private modalService: ModalService;
constructor(modalService: ModalService){
this.modalService = modalService
}
public async openChat(): Promise<void> {
this.modalService.openChat(this.userData);
}
modal.service
import { ModalController } from '@ionic/angular';
import { Injectable } from '@angular/core';
import { ProfileComponent } from '../../components/profile/profile.component';
import { ChatComponent } from '../../components/chat/chat.component';
import { UserData } from '../../interfaces/UserData/userData.interface';
@Injectable({
providedIn: 'root',
})
export class ModalService {
private modal: ModalController;
public constructor(modal: ModalController) {
this.modal = modal;
}
public async openProfileComponent(user: UserData): Promise<void> {
this.modal.dismiss();
const profile = await this.modal.create({
component: ProfileComponent,
componentProps: {
contact: user,
},
});
await profile.present();
}
public async openChatComponent(user: UserData): Promise<void> {
this.modal.dismiss();
const chat = await this.modal.create({
component: ChatComponent,
componentProps: {
contact: user,
},
});
await chat.present();
}
public close(): void {
this.modal.dismiss();
}
}
ОБНОВЛЕНИЕ Stackblitz слишком нестабилен с Ionic 4, поэтому я не могу скопировать его, поэтому вот gist с информацией и соответствующим кодом.
UPDATE2 Я воспользовался советом, упомянутым в ответах, но все еще получаю ошибку. Для этого я создал shared.module.ts
, который выглядит следующим образом:
import { UserService } from './componentServices/user/user.service';
import { ModalService } from './componentServices/modal/modal.service';
import { AuthenticationSecurityService } from './componentServices/auth_security/authentication-security.service';
import { AuthGuardService } from '../_guards/auth-guard.service';
import { ApiService } from './componentServices/api/api.service';
import { ChatService } from './components/chat/socketIO/chat.service';
@NgModule({
imports: [CommonModule, ReactiveFormsModule, IonicModule.forRoot(), FormsModule, IonicModule],
declarations: [
// various components
],
exports: [
// various components and common modules
],
})
export class SharedModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: SharedModule,
providers: [
UserService,
ModalService,
DashboardService,
AuthenticationSecurityService,
AuthGuardService,
ApiService,
ChatService,
],
};
}
}
app.module.ts
imports: [
SharedModule.forRoot(),
]
client:135 Circular dependency detected:
src/sharedModules/componentServices/modal/modal.service.ts -> src/sharedModules/components/profile/profile.component.ts -> src/sharedModules/componentServices/modal/modal.service.ts
client:135 Circular dependency detected:
src/sharedModules/components/chat/chat.component.ts -> src/sharedModules/components/search/search.component.ts -> src/sharedModules/components/profile/profile.component.ts -> src/sharedModules/componentServices/modal/modal.service.ts -> src/sharedModules/components/chat/chat.component.ts
client:135 Circular dependency detected:
src/sharedModules/components/profile/profile.component.ts -> src/sharedModules/componentServices/modal/modal.service.ts -> src/sharedModules/components/profile/profile.component.ts
client:135 Circular dependency detected:
src/sharedModules/components/search/search.component.ts -> src/sharedModules/components/profile/profile.component.ts -> src/sharedModules/componentServices/modal/modal.service.ts -> src/sharedModules/components/chat/chat.component.ts -> src/sharedModules/components/search/search.component.ts
РЕШЕНИЕ
как сказали @ bryan60 и @Luis, там должен быть буфер, поэтому я пошел по пути излучения, который они оба предложили. Брайан дает больше похожего кода, где Луис дает большую сводку ответственности. Вот как я его рефакторинг:
app.component.ts
public initializeApp(): void {
this.platform.ready().then((): void => {
this.statusBar.styleDefault();
this.splashScreen.hide();
this._subToObservables();
});
}
private _subToObservables(): void {
this.modalService.openModal$.subscribe(
async (e: ModalEmitInterface): Promise<void> => {
const { command, data } = e;
switch (command) {
case 'open-profile':
const profile = await this.modalCtrl.create({
component: ProfileComponent,
componentProps: {
contact: data,
},
});
await profile.present();
break;
case 'open-chat':
// same as above
break;
default:
break;
}
},
);
}
modalSignal.service.ts
export class ModalService {
private openModalSubject: Subject<ModalEmitInterface> = new Subject<ModalEmitInterface>();
public readonly openModal$: Observable<ModalEmitInterface> = this.openModalSubject.asObservable();
private emitPayload: ModalEmitInterface;
public openProfileComponent(user: UserData): void {
this.emitPayload = {
command: 'open-profile',
data: user,
};
this.openModalSubject.next(this.emitPayload);
}
// repeat for others
}
chat.component.html
<button (click)="openProfile(user)">click me</button>
chat.component.ts
export class ChatComponent {
public constructor(private modalSignal: ModalService){}
private openProfile(user: UserData): void {
this.modalSignal.openProfileComponent(user);
}
}
Вот и все, хотя вам все равно нужно убедиться, что вы закрываете модалы, или они будут продолжать складываться.