简体   繁体   English

Angular 4-检测到循环依赖。 两个组件导入了另一个组件的.ts文件

[英]Angular 4 - Circular dependency detected. Two components have the other component's .ts file imported

Currently working on resolving a circular dependency that's been introduced in our code base. 当前正在努力解决我们的代码库中引入的循环依赖。 Our team uses the webpack circular dependency plugin, so we're notified in the browser console if one of these circular dependencies is found. 我们的团队使用了webpack循环依赖插件,因此,如果找到了这些循环依赖之一,则会在浏览器控制台中通知我们。

Error in the browser console reads as follows: Circular dependency detected: 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.component.ts 浏览器控制台中的错误如下所示:检测到循环依赖项: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-people \\ demographics-form \\ demographics-form.component.ts-> src \\ app \\ domain \\ admin \\ employer \\ employer-form \\雇主form.component.ts

Relevant bits of employer-form.component.ts 雇主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);
    }
 ....

Relevant bits of people-form.component.ts people-form.component.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();
                    }
                }
            });
    }

Because of the two components importing the other component's file in the import statements, we're seeing the circular dependency warning. 由于这两个组件在import语句中导入了另一个组件的文件,因此我们看到了循环依赖警告。

What suggestions would anyone have for how to resolve this? 任何人对如何解决此问题有什么建议? Thanks in advance! 提前致谢!

I don't have a specific answer for you, but obviously the problem is the first line of the initializeForm() method in people-form.component: 我没有适合您的具体答案,但是显然问题出在people-form.component中的initializeForm()方法的第一行:

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

I recommend that you structure your code so that the PeopleFormComponent does not need to explicitly know about the EmployerFormComponent. 我建议您对代码进行结构化,以便PeopleFormComponent不需要显式了解EmployerFormComponent。

One way to do this would be to determine somewhere else whether you need to display the employer grid, and then perhaps pass a boolean into the route, or inject a shared service that has that information. 一种方法是在其他地方确定是否需要显示雇主网格,然后将布尔值传递给路线,或注入具有该信息的共享服务。

I'm also not sure that your current check works, since you are explicitly casting EmployerFormComponent to a Component. 我也不确定您当前的检查是否有效,因为您将EmployerFormComponent显式转换为Component。 Perhaps you just need to check whether this.model.options.activatorPanel is non-empty? 也许您只需要检查this.model.options.activatorPanel是否为非空?

If you really do need to check explicitly, create an interface and then have the EmployerFormComponent implement that interface. 如果确实需要显式检查,请创建一个接口,然后由EmployerFormComponent实现该接口。 Then check whether the "model.options.activatorPanel" implements that interface. 然后检查“ model.options.activatorPanel”是否实现了该接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM