【问题标题】:AngularJS - module dependencies, naming clashAngularJS - 模块依赖,命名冲突
【发布时间】:2015-08-03 04:36:11
【问题描述】:

我有两个第三方模块,都定义了一个同名的工厂。显然,我无法控制这些模块的命名,而无需求助于 kludge。

此外,我还有两个 internal 模块,每个模块都使用两个 third-party 模块中的一个作为依赖项(如下所示)。我确信我无法访问当前模块依赖项中未列出的模块中的组件,但事实证明我错了。

即使own1 依赖于thirdParty1(将hello 定义为hello world),它也会在控制器中获得hi there(来自thirdParty2)。其他模块对也是如此。

有没有办法“隔离”模块,这样我就只能使用我明确依赖的东西?如果没有,如果我可以随时访问任何内容(假设主应用程序模块将其作为其依赖项),那么拥有模块有什么意义?另外,如果我有两个模块,其中的组件名为 hello,我怎么知道要使用哪个?

这是 http://jsbin.com/vapuye/3/edit?html,js,output 的 jsbin

angular.module('app', ['own1', 'own2']);

//third-party modules
angular.module('thirdParty1', []).factory('hello', function () {
  return 'hello world';
});

angular.module('thirdParty2', []).factory('hello', function () {
  return 'hi there';
});

// "own" modules
angular.module('own1', ['thirdParty1']).controller('Own1Ctrl', function(hello) {
  this.greet = hello;
});

angular.module('own2', ['thirdParty2']).controller('Own2Ctrl', function(hello) {
  this.greet = hello;
});

结果:

<body ng-app="app">
  <div ng-controller="Own1Ctrl as own1">
    Own1: {{ own1.greet }}
  </div>
  <div ng-controller="Own2Ctrl as own2">
    Own2: {{ own2.greet }}
  </div>
</body>

是:

Own1: hi there
Own2: hi there

【问题讨论】:

  • 您实际上有两个定义同名服务的库吗?模块用于封装特定行为并帮助测试您的应用程序。
  • 模块服务于更多的结构和组织目的,而不是隔离。在引导时,所有模块都被打包到一个全局模块中,以便它们可以相互访问。
  • 如果您尝试使用的两个库具有内部结构,通常您可以只包含您正在使用的部分。例如,如果你想要 AngularUI-Bootstrap 和 AngularStrap 的一部分,你可以选择你包含的模块。 (AngularStrap 有mgcrea.ngStrap.modal,AngularUI-Bootstrap 有ui.bootstrap.modal)。通过仅包含您需要的部分,您可以确保从每个部分中获得正确的部分。
  • @NicholasThomson 就是这样!我正要摆脱其中一个,但这就是我被这东西咬得很厉害的地方。但是......即使我从第三方挑选子模块,如果它们仍然定义相同的组件,我还是会有命名冲突,不是吗?
  • 我相信 Angular 会更喜欢第二个模块。因此,如果您只使用 AngularStrap 中的 $modal ,请尝试以下操作:angular.module('app', ['ui-bootstrap', 'mcrea.ngStrap.modal']);

标签: javascript angularjs angularjs-module


【解决方案1】:

由于没有内置的模块(或模块的组件)名称间距,因此实现您的目标的最佳方法是为您的模块使用独特的命名约定。大多数 Angular 库都这样做,然后你就可以开始了。

除了封装您的应用程序行为之外,模块还有助于测试和模拟您的应用程序。

我认为 angular 不可能区分两个名称相同的组件(我认为这会随着 angular 2 的变化而变化)。我可能会争辩说,两个命名相同的组件可能会做同样的事情,你应该看看为什么你需要两者?

【讨论】:

  • 所以我真的不知道什么是模块以及所有这些依赖于的东西:) 目前我碰巧有两个模块(第三方)都定义了$modal,即使只有特定的一个被定义为我从另一个得到$modal 的依赖项。
  • 还对组件使用说“点表示法”,例如mymodule.myservice 很难用作函数参数(因为点)
  • 对于函数参数,您真的不应该使用原始组件名称。否则 javascript 缩小可能会打到你那里。看看数组初始化(例如.controller(['componentID', function(comp1){ ... }]);
  • 是的,知道这种语法,但我更喜欢使用 ngAnnotate 处理缩小而不是编写大量样板文件并在大多数情况下重复相同的内容。顺便说一句,您是用“点符号”命名组件还是使用任何其他约定?
  • 我倾向于使用camelCase,Component
【解决方案2】:

您可以显式请求某个模块的工厂(无需依赖注入):

var injector = angular.injector(['thirdParty1']);
var hello1 = injector.get('hello');

var injector = angular.injector(['thirdParty2']);
var hello2 = injector.get('hello');

您也可以使用它,将第三方工厂包装到自己的工厂中:

angular.module('own1', ['thirdParty1']).factory('hello1', function () {
  var injector = angular.injector(['thirdParty1']);
  var hello = injector.get('hello');
  return hello;
});

angular.module('own2', ['thirdParty2']).factory('hello2', function () {
  var injector = angular.injector(['thirdParty2']);
  var hello = injector.get('hello');
  return hello;
});

这允许您在应用程序的所有其他部分中使用hello1hello2

【讨论】:

  • 是的,但这太难了:)
  • 这有什么不妥之处?您只需在应用程序中定义两个包装器,然后您就可以在其他任何地方使用您的两个工厂,而无需担心名称冲突。对我来说,这将是一个非常优雅的解决方案。但我猜人们有不同的标准;)
  • 啊,我误会了你一点(很着急)。这很好,只要你包装一些东西供你的应用程序使用。 hacky 我的意思是,如果您每次需要给予 dep 时都必须致电 $injector。这将完全反对 DI 的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-04
  • 1970-01-01
  • 1970-01-01
  • 2016-12-06
  • 1970-01-01
  • 2017-11-15
  • 1970-01-01
相关资源
最近更新 更多