考虑以下jfiddle http://jsfiddle.net/bchapman26/9uUBU/29/
//angular.js example for factory vs service
var app = angular.module('myApp', ['module1', 'module2']);
var service1module = angular.module('module1', []);
service1module.factory('myService', function() {
return {
sayHello: function(text) {
return "Service1 says \"Hello " + text + "\"";
},
sayGoodbye: function(text) {
return "Service1 says \"Goodbye " + text + "\"";
}
};
});
var service2module = angular.module('module2', []);
service2module.factory('myService', function() {
return {
sayHello: function(text) {
return "Service2 says \"Hello " + text + "\"";
},
sayGoodbye: function(text) {
return "Service2 says \"Goodbye " + text + "\"";
}
};
});
function HelloCtrl($scope, myService) {
$scope.fromService1 = myService.sayHello("World");
}
function GoodbyeCtrl($scope, myService) {
$scope.fromService2 = myService.sayGoodbye("World");
}
我有2个模块(module1和module2)。 module1和module2都定义了一个名为myService的服务。当两个模块都导入myApp时,这似乎会在Angular中的myService上创建名称冲突。看来AngularJs只使用第二个服务定义而没有警告您可能出现的问题。
非常大的项目(或者只是重复使用模块)会有名称冲突的风险,这可能很难调试。
有没有办法为名称添加模块名称,以便不会发生名称冲突?
答案 0 :(得分:62)
截至今天,AngularJS模块不提供任何类型的命名空间,以防止不同模块中的对象之间发生冲突。原因是AngularJS应用程序有一个注入器,它保存所有对象的名称而不考虑模块名称。
管理依赖关系创建的责任,每个Angular 应用程序有一个注射器注入器是一个服务定位器 负责构建和查找依赖项。
正如您所提到的,将模块注入主/ app模块时可能会产生令人讨厌的错误。碰撞发生时,它们是静音的,胜者是由最后一个模块注入的。
所以不,没有内置的方法来避免这些碰撞。也许这将在未来发生。对于更有可能出现此问题的大型应用程序,您认为命名约定是最佳工具是正确的。考虑属于模块或功能区域的对象是否可能使用短前缀。
答案 1 :(得分:2)
您可以通过使用约定命名模块来避免这种情况,以便它们始终是唯一的。
一种方法是看其他语言是如何做到的。例如,在Java中,类的“全名”基于文件的名称及其所在的文件夹。例如,如果在MyArtStuff文件夹中有一个名为Bitmap.java的Java文件,则该类的全名将为是MyArtStuff.Bitmap
结果证明,AngularJS允许您将点(。)作为模块名称的一部分,因此您基本上可以使用名称约定。
例如,如果开发人员在脚本“MainPage \ Module1.js”中创建名为“ModuleA”的模块,则应将其模块命名为“MainPage.Module1.ModuleA”。由于每个路径和文件名在您的应用中都是唯一的,因此您的模块名称将是唯一的。
您只需要让开发人员遵循此惯例。
请注意,Rockallite指出这对多个模块中具有相同名称的服务,控制器等没有帮助。但是你可以使用类似的方法得到结果,并为这些元素的名称添加前缀。
理想情况下,AngularJS会有名称空间,将来也可能。在此之前,我们所能做的最好的事情就是在开发名称空间之前40多年来开发人员已做的事情,并尽可能地为我们的元素添加前缀。
答案 2 :(得分:0)
不幸的是, AngularJS 中没有namespacing
。一种解决方案是使用prefix
(另一种解决方案可能是this!)。请参阅以下示例:
// root app
const rootApp = angular.module('root-app', ['app1', 'app2']);
// app 1
const app1 = angular.module('app1', []);
app1.controller('app1.main', function($scope) {
$scope.msg = 'App1';
});
// app2
const app2 = angular.module('app2', []);
app1.controller('app2.main', function($scope) {
$scope.msg = 'App2';
})

<!-- angularjs@1.7.0 -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.0/angular.min.js"></script>
<!-- root app -->
<div ng-app="root-app">
<!-- app 1 -->
<div ng-controller="app1.main">
{{msg}}
</div>
<!-- app 2 -->
<div ng-controller="app2.main">
{{msg}}
</div>
</div>
&#13;
答案 3 :(得分:-8)
在您希望服务来自的模块上定义控制器。
service2Module.controller("ServiceTwoCtrl", function(myService, $scope) {});