Módulos y colisión del espacio de nombres / nombre en AngularJS

Considere el siguiente 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"); }​ 

Tengo 2 módulos (módulo1 y módulo2). Tanto el módulo1 como el módulo2 definen un servicio llamado myService. Esto parece crear un choque de nombre en myService dentro de Angular cuando ambos módulos se importan en myApp. Parece que AngularJs solo usa la segunda definición de servicio sin avisarle del posible problema.

Los proyectos muy grandes (o simplemente la reutilización de módulos en general) tendrían el riesgo de que los nombres entren en conflicto, lo que podría ser difícil de depurar.

¿Hay alguna manera de prefijar los nombres con el nombre del módulo para que los conflictos de nombres no sucedan?

A partir de hoy, los módulos AngularJS no proporcionan ningún tipo de espacio de nombres que evite las colisiones entre objetos en diferentes módulos. La razón es que una aplicación AngularJS tiene un único inyector que contiene nombres para todos los objetos sin importar los nombres de los módulos.

La Guía para desarrolladores de AngularJS dice:

Para administrar la responsabilidad de la creación de dependencia, cada aplicación angular tiene un inyector. El inyector es un localizador de servicios que es responsable de la construcción y búsqueda de dependencias.

Como ha mencionado, pueden surgir errores desagradables al inyectar módulos en su módulo principal / aplicación. Cuando ocurren colisiones, son silenciosas y el ganador se determina según el último módulo inyectado.

Entonces, no, no existe una forma integrada de evitar estas colisiones. Quizás esto sucederá en el futuro. Para aplicaciones grandes donde este problema es más probable, tienes razón en que las convenciones de nomenclatura son tu mejor herramienta. Considere si los objetos que pertenecen a un módulo o área de función pueden usar un prefijo corto.

Puede evitar esta situación usando una convención para nombrar sus módulos para que siempre sean únicos.

Un enfoque es observar cómo lo hacen otros idiomas. Por ejemplo, en Java, el “nombre completo” de la clase se basa en el nombre del archivo y la carpeta en la que se encuentra. Por ejemplo, si tiene un archivo Java llamado Bitmap.java en la carpeta MyArtStuff, el nombre completo de la clase ser MyArtStuff.Bitmap

Resulta que AngularJS le permite tener puntos (.) Como parte del nombre de su módulo para que pueda usar básicamente la convención de nombre.

Por ejemplo, si un desarrollador crea un módulo llamado “ModuleA” en el script “MainPage \ Module1.js”, debe nombrar su módulo “MainPage.Module1.ModuleA”. Debido a que cada ruta de acceso y nombre de archivo es única en su aplicación, el nombre de su módulo será único.

Simplemente tendrías que hacer que tus desarrolladores sigan esta convención.

Tenga en cuenta que Rockallite señala que esto no ayudará con los servicios, controladores, etc. con el mismo nombre en múltiples módulos. Pero puede usar un enfoque similar para dar como resultado y también ponerle un prefijo a los nombres de esos elementos.

Idealmente AngularJS tendría espacios de nombres y en el futuro podría ser. Hasta entonces, lo mejor que podemos hacer es hacer lo que los desarrolladores han estado haciendo durante más de 40 años antes de que se inventaran los espacios de nombres y prefijar nuestros elementos lo mejor que podamos.

Lamentablemente, no hay namespacing de namespacing en AngularJS . Una solución es usar un prefix (¡otra solución puede ser esta !). Vea el siguiente ejemplo:

 // 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'; }) 
    
{{msg}}
{{msg}}

Defina sus controladores en el módulo del que desea que sea el servicio.

service2Module.controller("ServiceTwoCtrl", function(myService, $scope) {});