简体   繁体   English

Angular-Material 对话框模块中的循环依赖

[英]Circular Dependancy in Angular-Material Dialog Module

I'm working with Angular 8 and I have a login modal with a link to the signup modal, and vice-versa.我正在使用 Angular 8,我有一个登录模式,其中包含指向注册模式的链接,反之亦然。 Both modals are opened from the authService.两种模式都是从 authService 打开的。 The problem is that the authService needs a reference to the login and signup components in order to open them.问题是 authService 需要引用登录和注册组件才能打开它们。 I just can't find a way to avoid the circular dependency there.我只是找不到一种方法来避免那里的循环依赖。

I searched google and stackoverflow and the best solution I found was to deactivate circular dependency warnings in the angular.json file, which is not the solution I'm looking for.我搜索了 google 和 stackoverflow,我找到的最佳解决方案是停用 angular.json 文件中的循环依赖警告,这不是我正在寻找的解决方案。 I shorten the 3 relevant files to only show the relevant code.我缩短了 3 个相关文件以仅显示相关代码。 It's all working fine, I just want to get rid of the error message and not face any unexpected problems later on and I try to find out what the correct way is of doing this.一切正常,我只想摆脱错误消息,以后不要遇到任何意外问题,我试图找出这样做的正确方法。

export class AuthService {
  loginModalRef: MatDialogRef<LoginComponent>;
  signupModalRef: MatDialogRef<SignupComponent>;

  constructor(
    private dialog: MatDialog
    ) {}

  closeLoginModal(): void {
    this.loginModalRef.close();
  }

  closeSignupModal(): void {
    this.signupModalRef.close();
  }

  openLoginModal(): void {
    if (this.signupModalRef) {
      this.closeSignupModal();
    }
    this.loginModalRef = this.dialog.open(LoginComponent, {panelClass: 'login-dialog'});
  }

  openSignupModal(): void {
    if (this.loginModalRef) {
      this.closeLoginModal();
    }
    this.signupModalRef = this.dialog.open(SignupComponent, {panelClass: 'signup-dialog'});
  }
}


export class LoginComponent implements OnInit {
  loginForm: FormGroup;

  constructor(
    private authService: AuthService
  ) {}

//when user clicks on 'Signup instead'
  openSignupModal() {
    this.authService.openSignupModal();
  }
}



@Component({
  selector: 'app-signup',
  templateUrl: './signup.component.html',
  styleUrls: ['./signup.component.scss']
})
export class SignupComponent implements OnInit {
  constructor(
    private authService: AuthService
  ) {}

// when user clicks on 'Login instead'
  openLoginModal() {
    this.authService.openLoginModal();
  }

// when user clicks on 'Terms of Services' the modal closes
  closeSignupModal() {
    this.authService.closeSignupModal();
  }
}

This is the error message:这是错误消息:

WARNING in Circular dependency detected: src\\app\\auth\\auth.service.ts -> src\\app\\auth\\login\\login.component.ts -> src\\app\\auth\\auth.service.ts检测到循环依赖项中的警告:src\\app\\auth\\auth.service.ts -> src\\app\\auth\\login\\login.component.ts -> src\\app\\auth\\auth.service.ts

WARNING in Circular dependency detected: src\\app\\auth\\login\\login.component.ts -> src\\app\\auth\\auth.service.ts -> src\\app\\auth\\login\\login.component.ts检测到循环依赖项中的警告:src\\app\\auth\\login\\login.component.ts -> src\\app\\auth\\auth.service.ts -> src\\app\\auth\\login\\login.component.ts

WARNING in Circular dependency detected: src\\app\\auth\\signup\\signup.component.ts -> src\\app\\auth\\auth.service.ts -> src\\app\\auth\\signup\\signup.component.ts检测到循环依赖项中的警告:src\\app\\auth\\signup\\signup.component.ts -> src\\app\\auth\\auth.service.ts -> src\\app\\auth\\signup\\signup.component.ts

you should probably restructure your app a bit here so that your login and signup components are wrapped by a modal component.您可能应该在这里稍微重构您的应用程序,以便您的登录和注册组件由模态组件包装。

@Component({
  template: `<app-login></app-login>`
})
export class LoginModalComponent { .. whatever in here, maybe something useful .. }

then your service would instantiate the LoginModalComponent那么您的服务将实例化LoginModalComponent

this.loginModalRef = this.dialog.open(LoginModalComponent, {panelClass: 'login-dialog'});

this avoids the circular dependency of LoginComponent -> AuthService and AuthService -> LoginComponent,这避免了 LoginComponent -> AuthService 和 AuthService -> LoginComponent 的循环依赖,

now its LoginModalComponent -> AuthService -> LoginComponent现在它的 LoginModalComponent -> AuthService -> LoginComponent

the wrapper component can likely also take some of the logic inside your login component for better modularity.包装器组件也可能采用登录组件内部的一些逻辑,以获得更好的模块化。

another option is a sort of remote service that gets injected into auth service and the login component另一种选择是一种远程服务,它被注入到身份验证服务和登录组件中

@Injectable()
export class ModalRemoteService {
  private closeLoginSource = new Subject();
  closeLogin$ = this.closeLoginSource.asObservable();
  private openLoginSource = new Subject();
  openLogin$ = this.openLoginSource.asObservable();

  closeLoginModal(): void {
    this.closeLoginSource.next();
  }

  openLoginModal(): void {
    this.openLoginSource.next();
  }
}

and auth service subscrsibes to these signals and login / signup component triggers them, this way you no longer need to inject auth into login.和 auth 服务订阅这些信号并且登录/注册组件触发它们,这样您就不再需要将 auth 注入登录。

You generally have a structural issue where you're using a service to instantiate and destroy components from within the components that you must solve somehow.您通常会遇到一个结构性问题,即您使用服务从必须以某种方式解决的组件中实例化和销毁组件。 generally with wrappers or remotes.通常带有包装器或遥控器。

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

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