Подтвердить что ты не робот

Модули и конфликты имен/имен в AngularJS

Рассмотрим следующий 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). Оба модуля1 и module2 определяют службу myService. Кажется, создается конфликт имен в myService в Angular, когда оба модуля импортируются в myApp. Похоже, что AngularJs просто использует второе определение сервиса, не предупредив вас о возможной проблеме.

Очень большие проекты (или просто повторное использование модулей в целом) могут столкнуться с риском столкновения имен, что может быть сложно отлаживать.

Есть ли способ префиксных имен с именем модуля, чтобы не произошло столкновений имен?

4b9b3361

Ответ 1

На сегодняшний день модули AngularJS не предоставляют каких-либо пространств имен, которые предотвратили бы столкновения между объектами в разных модулях. Причина в том, что приложение AngularJS имеет один инжектор, который содержит имена для всех объектов без учета имен модулей.

Руководство разработчика AngularJS говорит:

Чтобы управлять ответственностью за создание зависимостей, каждый Angularприложение имеет инжектор. Инжектор - это локатор обслуживания, который ответственный за строительство и поиск зависимостей.

Как вы уже упоминали, неприятные ошибки могут возникнуть при вводе модулей в ваш основной модуль/приложение. Когда происходят столкновения, они молчат, и победитель определяется тем, какой последний модуль был введен.

Так нет, нет встроенного способа избежать этих столкновений. Возможно, это произойдет в будущем. Для крупных приложений, где эта проблема становится более вероятной, вы правы, что соглашения об именах - ваш лучший инструмент. Рассмотрим, могут ли объекты, принадлежащие модулю или области функций, использовать короткий префикс.

Ответ 2

Вы можете избежать этой ситуации, используя соглашение для обозначения своих модулей, чтобы они всегда были уникальными.

Один из подходов - посмотреть, как это делают другие языки. Например, в Java "полное имя" класса основано на имени файла и его папке. Например, если у вас был файл Java Bitmap.java в папке MyArtStuff, полное имя класса было бы be MyArtStuff.Bitmap

Выключает AngularJS позволяет вам иметь точки (.) как часть имени вашего модуля, чтобы вы могли в принципе использовать соглашение о названии.

Например, если разработчик создал модуль под названием "ModuleA" в script "MainPage\Module1.js", он должен назвать свой модуль "MainPage.Module1.ModuleA". Поскольку каждый путь и имя файла уникальны в вашем приложении, ваше имя модуля будет уникальным.

Вам просто нужно заставить своих разработчиков следовать этому соглашению.

Обратите внимание, что, как отмечает Rockallite, это не поможет службам, контроллерам и т.д. с одинаковым именем в нескольких модулях. Но вы можете использовать аналогичный подход, чтобы получить результат и префикс имен этих элементов.

В идеале AngularJS будет иметь пространства имен, и в будущем это может произойти. До тех пор самое лучшее, что мы можем сделать, это делать то, что разработчики делали уже более 40 лет, прежде чем были созданы пространства имен и префикс наших элементов, которые мы можем наилучшим образом.

Ответ 3

Определите свои контроллеры в модуле, из которого вы хотите, чтобы служба была.

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