【问题标题】:Injecting modules in extended controller(ES6) causes Unknown provider error在扩展控制器(ES6)中注入模块会导致未知提供程序错误
【发布时间】:2016-05-04 15:17:38
【问题描述】:

我有一个控制器类ModalCtrl,我想创建一个子类ModalCtrlChild extends ModalCtrl。问题是当我尝试这样做时,在ModalCtrl 中注入的任何模块中都会出现未知的提供程序错误。

我使用this 生成器构建项目,它在幕后使用 NgInject 注入依赖项,我怀疑那里发生了一些有趣的事情。

模态控件:

export default class ModalCtrl {
  static get UID(){
    return "ModalCtrl"
  }
  ... // all my ModalCtrl methods here

 /* @ngInject */
  constructor(ngDialog, PreoModalType, OutletService, $q, $timeout, VenueService) {
    "ngInject";
    ... // ModalCtrl constructor logic initing variables
  }
}

ModalCtrlChild:

import ModalCtrl from '../../preoModal.controller';

export default class ModalCtrlChild  extends ModalCtrl{
  static get UID(){
    return "modalCtrlChild"
  }

  /* @ngInject */
  constructor() {
    // "ngInject";
    console.log("in super constructor");
    super();
  }
}

错误:

Error: [$injector:modulerr] Failed to instantiate module function ModalCtrlChild() due to:
Error: [$injector:unpr] Unknown provider: ngDialog
http://errors.angularjs.org/1.5.3/$injector/unpr?p0=ngDialog

ngDialog 绝对已导入并正常工作。如果从 ModalCtrlChild 删除 extends ModalCtrl 我不会收到任何错误,并且我的代码运行良好,但我无法获得所需的继承。任何想法表示赞赏。

编辑

我在发布问题之前尝试过 eenagy 的回答,但这也不起作用,因为问题似乎出在子类注入中,而不是在父类注入中。

sourdoughdetzel,试试你的建议:

  1. 从 ModalCtrlChild 中移除注释和依赖项
  2. 从 ModalCtrl 中删除注释和依赖项,但将它们留在子项中

得到完全相同的错误:

Error: [$injector:modulerr] Failed to instantiate module function PreoModalController_Form() due to:
Error: [$injector:unpr] Unknown provider: ngDialog

我怀疑这与 babel 构建扩展类的方式有关,并且不允许 ngInject 完成它的工作。我正在尝试在这里找到一种手动注入的方法,这应该可以解决问题并证明这是问题所在,因为我对 babel 如何解决此问题了解不足。

【问题讨论】:

  • “ngDialog 绝对是导入并正常工作” 没关系。问题是它是否可以作为控制器模块中的服务使用。此外,如果ModalCtrl 的构造函数需要参数,那么当您在ModalCtrlChild 的构造函数中调用super 时,您必须传递这些参数。顺便说一句,错误消息看起来很奇怪。似乎您尝试将控制器实例化为模块。这段代码是什么样子的?
  • @caiocpricci2 你解决了吗?
  • 我已经多玩了一点,它在注入 ng-dialog 时对我来说可以正常工作...
  • @eenagy,不,我没有解决这个问题。您可以发布一个使用 nginject 的覆盖类示例的 jsfiddle 吗?
  • @caiocpricci2 使用与您相同的生成器,这是为我工作的示例:github.com/eenagy/ngInject-demo

标签: javascript angularjs webpack ecmascript-6 babeljs


【解决方案1】:

我的猜测是,当您从子类的构造函数中调用“super()”时,ngInject 并没有做它应该在幕后做的事情。在四处搜索时,我在 ngInject 上没有看到太多内容,但由于手动调用正在发生的构造函数,它可能会短路。

如果您将依赖项放入 ModalCtrlChild 控制器并取消注释“ngInject”字符串,然后将它们传递给 super() 调用,它是否按预期工作?

【讨论】:

  • 感谢您的建议,但我遇到了同样的错误。在我看来,babel 在编译代码时做了一些意想不到的事情,并且在扩展类时不允许注释。
【解决方案2】:

错误信息实际上告诉你缺少什么。

Unknown provider: ngDialog

你也需要在你的子类中声明你的依赖。

所以不是这个

import ModalCtrl from '../../preoModal.controller';

export default class ModalCtrlChild  extends ModalCtrl{
  static get UID(){
    return "modalCtrlChild"
  }

  /* @ngInject */
  constructor() {
    // "ngInject";
    console.log("in super constructor");
    super();
  }
}

需要传入参数。

import ModalCtrl from '../../preoModal.controller';

export default class ModalCtrlChild  extends ModalCtrl{
  static get UID(){
    return "modalCtrlChild"
  }

  /* @ngInject */
  constructor(ngDialog, PreoModalType, OutletService, $q, $timeout, VenueService) {
    // "ngInject";
    console.log("in super constructor");
    super(ngDialog, PreoModalType, OutletService, $q, $timeout, VenueService);
  }
}

ngInject 无法知道需要哪些依赖项。它应该怎么知道?在现实世界中可能有几十个 ngDialog 的子类,它们与合约匹配并且可以作为参数传递。您需要指定需要哪个,以便它可以传入。

例如,假设您有一个名为 ngPopupDialog 的 ngDialog 子类。

还有你的示例子类。以下可以用来代替 ngDialog,并且会匹配 super。

import ModalCtrl from '../../preoModal.controller';

export default class ModalCtrlChild  extends ModalCtrl{
  static get UID(){
    return "modalCtrlChild"
  }

  /* @ngInject */
  constructor(ngPopupDialog, PreoModalType, OutletService, $q, $timeout, VenueService) {
    // "ngInject";
    console.log("in super constructor");
    super(ngPopupDialog, PreoModalType, OutletService, $q, $timeout, VenueService);
  }
}

【讨论】:

  • "你需要传入参数。"这是我在这里提出问题之前尝试的第一件事,它给了我同样的错误。 “它应该怎么知道?在现实世界中,可能有几十个与合同相匹配的 ngDialog 子类”我不明白这与这个问题的上下文有什么关系。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多