【问题标题】:Ionic2/Angular2 Cyclical DependenciesIonic2/Angular2 循环依赖
【发布时间】:2017-02-01 08:50:15
【问题描述】:

我正在使用 Ionic 2 rc4。

我遇到了一个问题,由于循环依赖而出现错误。

  +-------------------------------------+
  |    LoginEmailPage    RegisterPage   |
  |           ↓           ↓↑            |
  |           UtilityService            |
  +-------------------------------------+

我有一个使用UtilityService 的类LoginEmailPage

例如来自LoginEmailPage

this.utilityService.login(nav)

UtilityService:

public login(nav: NavController): void {
    nav.popTo(RegisterPage);
}

RegisterPage 也使用了utilityService,所以我得到一个编译时错误:

metadata_resolver.js:623Uncaught Error: Can't resolve all parameters for LoginEmailPage: (FirebaseAuth, MenuController,

NavController、NavParams、FormBuilder、ViewController、 AlertController、PersonService、?、事件、LoadingController)。 在 CompileMetadataResolver._getDependenciesMetadata (http://localhost:8100/build/main.js:39298:19)

?UtilityService

问题

如何让服务 (UtilityService) 导航到已引用服务 (UtilityService) 的页面 (RegisterPage)?

谢谢

更新

由于以下建议:

基于this,我尝试过使用Injector

utilityService.ts

import { Injectable, Injector } from "@angular/core";

    private registerPage: RegisterPage = null;
    constructor(injector: Injector,...
        setTimeout(() => this.registerPage = injector.get(RegisterPage));

    public login(nav: NavController): void {
        nav.popTo(this.registerPage);
    }

但我仍然遇到与上述相同的错误。

其次,我看thisthis,建议使用forwardRef。我的问题是我的服务是@Injectable 而不是@Component。所以我看到的examples 做了类似的事情:

@Component({
  selector: 'my-button',
  template: `<div>
               <icon></icon>
               <input type="button" />
             </div>`,
  directives: [forwardRef(() => MyIcon)] // MyIcon has not been defined yet
})                                       // forwardRef resolves as MyIcon when MyIcon is needed

问题

我怎样才能让它与不是组件而是可注入的服务一起使用?

更新

更多信息,我正在添加每个文件的构造函数。

loginemail.ts

@Component({
    templateUrl: 'loginemail.html'
})

export class LoginEmailPage {
...
    constructor(public auth: FirebaseAuth, menu: MenuController, public nav: NavController, public navParams: NavParams, public builder: FormBuilder, public viewCtrl: ViewController, alertCtrl: AlertController, personService: PersonService, utilityService: UtilityService, events: Events, public loadingCtrl: LoadingController) {

register.ts

@Component({
    templateUrl: 'register.html'
})

export class RegisterPage {
...
    constructor(public nav: NavController, public navParams: NavParams, public builder: FormBuilder, personService: PersonService,
        public viewCtrl: ViewController, public alertCtrl: AlertController, utilityService: UtilityService, events: Events,
        public loadingCtrl: LoadingController, public auth: FirebaseAuth) {

utilityService.ts

@Injectable()
export class UtilityService {
...
    constructor(injector: Injector, alertCtrl: AlertController, menu: MenuController, popoverController: PopoverController, storage: Storage) {

更新

感谢下面的建议,我试试this

utilityService.ts

import { Injectable, Inject, forwardRef } from "@angular/core";
import { RegisterPage } from '../register/register';

@Injectable()
export class UtilityService {
...

public registerPage: RegisterPage = null;

     constructor(@Inject(forwardRef(() => RegisterPage)) registerPage, ...
        this.registerPage = registerPage;
          ...
          nav.popTo(this.registerPage, { personModel });

但是我还是原来的编译错误。我一定做错了什么。有什么想法吗?

更新

RegisterPage,我使用forwardRef

constructor(@Inject(forwardRef(() => UtilityService)) utilityService

但我收到以下错误:

错误:RegisterPage 没有提供程序!

所以我将RegisterPage 添加到providers 中的app.modula.ts,然后我得到:

Error: Uncaught (in promise): Error: Provider parse errors:
Cannot instantiate cyclic dependency! RegisterPage: in NgModule AppModule
Error: Provider parse errors:
Cannot instantiate cyclic dependency! RegisterPage: in NgModule AppModule

【问题讨论】:

  • 你可以使用前向引用angular.io/docs/ts/latest/cookbook/…
  • 感谢您的帮助,但我已经按照你们的建议尝试了 InjectorforwardRef,但都无法正常工作。我已经更新了我上面的解释,以包含更多细节。如果您能提出任何建议,我将不胜感激。
  • 如果每个类都在自己的文件中,则 forwardRef 应该不是必需的。仅当您需要在同一文件中进一步引用类时,forwardRef 才是必需的。
  • 我想我们需要查看所有涉及的服务和组件类的构造函数列表。

标签: angular ionic2


【解决方案1】:

尝试在组件的构造函数中使用forwardRef 例如:

export class LoginEmailPage {
constructor(...
     @Inject(forwardRef(() => UtilityService))utilityService, events: Events,
        public loadingCtrl: LoadingController, public auth: FirebaseAuth) {

查看here

RegisterPageLoginEmailPage 也是组件而不是提供者(可注入)。不应在 UtilityService 的构造函数中设置。

【讨论】:

  • 您好 Suraj,感谢您的意见。我已经尝试了你的建议,但我一定做错了什么。请你看看我上面描述中的更新。
  • 或尝试登录页面,因为那里出现错误。我不知道您的依赖关系图是否知道循环是
  • 我可以从RegisterPageLoginEmailPage 引用UtilityService,所以我需要在UtilityPage 中执行此操作。我将更新上面的描述以更清楚地显示我的依赖关系。
  • 您是在 loginemailpage 中导入注册页面吗?
  • 我不认为forwardRef 会起作用,因为我认为循环依赖的import 会导致错误。我确实看过使用require,但也无法让它工作。 (例如this.pages['RegisterPage'] = require('../register/register').RegisterPage;
猜你喜欢
  • 1970-01-01
  • 2016-05-30
  • 2010-09-12
  • 2021-10-02
  • 1970-01-01
相关资源
最近更新 更多