角度 4 - 检测到圆形依赖关系。两个组件导入了另一个组件的 .ts 文件



目前正在解决代码库中引入的循环依赖关系。我们的团队使用 webpack 循环依赖插件,因此如果找到这些循环依赖之一,我们会在浏览器控制台中收到通知。

浏览器控制台中的错误如下所示: 检测到循环依赖关系: src\app\domain\admin\employer\employer-form\employer-form.component.ts -> src\app\domain\admin\people\people-form\people-form.component.ts ->> src\app\domain\admin\people\people-form\demographics-form\demographics-form.component.ts -> src\app\domain\admin\employer\employer-form\employer-form\employer-form.component.ts

雇主表单.组件的相关部分

import { PanelTypesEnum } from '../../core/enums/panel-types.enum';
import { PeopleFormComponent } from '../../people/people-form/people-form.component';
import { PeopleService } from '../../people/people.service';
@Component({
selector: 'hl2-employer-form',
templateUrl: 'employer-form.component.html',
styleUrls: ['employer-form.component.scss']
})
export class EmployerFormComponent extends BaseComponentService implements OnInit, OnDestroy {
@Input() model: PanelModel;
...
constructor(route: ActivatedRoute,
...) {
super(route);
}
ngOnInit() {
this.initializeForm();
this.componentInitialize();
this.initializeSubscriptions();
}

confirmCancel(): void {
if (!this.employerForm.pristine || this.employerForm.dirty) {
this.adminConfirmationService.confirm(this.confirmation);
} else {
this.navigateAwayFromForm();
}
}
componentInitialize(): void {
this.confirmation = {message: '', accept: () => { this.navigateAwayFromForm(); }};
this.panelService.onPanelHide.takeUntil(this.ngUnsubscribe)
.subscribe(panel => {
if (panel && panel.id === this.model.id) {
this.confirmCancel();
} else if (this.panelService.verifyEditFormPanelRequiresConfirmation(this.model, panel)) {
this.confirmation.databag = <PanelModel>panel;
this.confirmCancel();
} else {
this.navigateAwayFromForm();
}
});
}
navigateAwayFromForm(): void {
let panel: PanelModel;
this.employerForm.reset('');
this.panelService.removePanel(this.model);
// in the case this form was activated by people form, only allow the user to navigate back to the people form on cancel, or pill click.
if (this.model.options.activatorPanel === <Component>PeopleFormComponent) {
if (this.peopleService.person.getValue().peopleId) {
// need to check current person in peopleService to determine if there is
// a peopleId assigned. If so, we need to redirect the user back to edit people form.
this.adminPanelService.newPeoplePanel(PanelTypesEnum.EditPeople, <Component>PeopleFormComponent,
<Component>EmployerFormComponent, false);
} else {
this.adminPanelService.newPeoplePanel(PanelTypesEnum.CreatePeople, <Component>PeopleFormComponent,
<Component>EmployerFormComponent, false);
}
return;
}
// otherwise, set next panel onFormClosed
if (this.confirmation.databag instanceof PanelModel) {
panel = this.confirmation.databag;
} else {
panel = this.adminPanelService.getEmployerGridPanel();
}
this.panelService.onFormClosed.next(panel);
}
....

人员表单的相关位.组件.ts

import { EmployerFormComponent } from '../../employer/employer-form/employer-form.component';
import { DisplayDateTimePipe } from 'shared/date.pipe';
import { PeopleConstants } from '../../core/constants/people-constants';
@Component({
selector: 'hl2-people-form',
templateUrl: './people-form.component.html',
styleUrls: ['./people-form.component.scss']
})
export class PeopleFormComponent extends BaseComponentService implements OnInit, OnDestroy {
@Input() model: PanelModel;
@ViewChild(DemographicsFormComponent) demographicsFormComponent: DemographicsFormComponent;
...
...
showEmployerGrid: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor(route: ActivatedRoute,
...) {
super(route);
}
ngOnInit(): void {
this.componentInitialize();
this.initializeForm();
this.initializeSubscriptions();
}
public initializeForm(): void {
if (this.model.options.activatorPanel === <Component>EmployerFormComponent) {
this.showEmployerGrid.next(true);
}
this.peopleForm = PeopleFormUtils.newPeopleForm(this.formBuilder);
this.nameTypeOptions = AdminConstants.nameTypeOptions();
this.prefixOptions = AdminConstants.prefixOptions();
this.suffixOptions = AdminConstants.suffixOptions();
this.professionalSuffixOptions = AdminConstants.professionalSuffixOptions();
this.genderOptions = PeopleFormUtils.translateGenderOptions(this.translateService);
this.maritalOptions = AdminConstants.maritalStatusOptions();
this.languageOptions = AdminConstants.languageOptions();
this.races = AdminConstants.metaDataList.races;
this.ethnicities = AdminConstants.metaDataList.ethnicities;
}
navigateAwayFromForm(): void {
let panel: PanelModel;
this.demographicsFormComponent.demographicsForm.reset('');
this.panelService.removePanel(this.model);
// in the case this form was activated by user form, only allow the user to navigate back to the user form on cancel, or pill click.
if (this.model.options.activatorPanel === <Component>UserFormComponent) {
// override default requireConfirmation setting, since this is reopening the people grid modal within the user form.
this.adminPanelService.newUserPanel(PanelTypesEnum.CreateUser, <Component>UserFormComponent, <Component>PeopleFormComponent, false);
return;
}
// otherwise, set next panel onFormClosed
if (this.confirmation.databag instanceof PanelModel) {
panel = this.confirmation.databag;
} else {
panel = this.adminPanelService.getPeopleGridPanel();
}
this.panelService.onFormClosed.next(panel);
}
componentInitialize(): void {
this.confirmation = {
message: '', accept: () => {
this.navigateAwayFromForm();
}
};
this.panelService.onPanelHide.takeUntil(this.ngUnsubscribe)
.subscribe((panel) => {
//probably x click from pill
if (panel && panel.id === this.model.id) {
this.confirmCancel();
} else if (this.panelService.verifyEditFormPanelRequiresConfirmation(this.model, panel)) {
this.confirmation.databag = <PanelModel>panel;
if (this.areFormsDirty()) {
this.confirmCancel();
} else {
this.navigateAwayFromForm();
}
}
});
}

由于两个组件在导入语句中导入了另一个组件的文件,因此我们看到了循环依赖项警告。

有人对如何解决这个问题有什么建议?提前感谢!

我没有具体的答案给你,但显然问题是people-form.component中initializeForm()方法的第一行:

if (this.model.options.activatorPanel === <Component>EmployerFormComponent)

我建议您构建代码,以便PeopleFormComponent不需要显式了解EmployerFormComponent。

一种方法是确定其他地方是否需要显示雇主网格,然后将布尔值传递到路由中,或者注入具有该信息的共享服务。

我也不确定您当前的检查是否有效,因为您正在显式地将 EmployerFormComponent 转换为组件。也许你只需要检查这个.model.options.activatorPanel是否为非空?

如果您确实需要显式检查,请创建一个接口,然后让 EmployerFormComponent 实现该接口。然后检查"model.options.activatorPanel"是否实现了该接口。

最新更新