Когда использовать $ инжектор в AngularJS
Когда я разбираю документацию AngularJS, я решил опубликовать эту статью, чтобы узнать другие мнения.
Мой конкретный сценарий состоит в том, что у меня есть настройки, которые я хочу изменить для инъекций, используя метод run моего модуля. У меня есть несколько разных способов доступа к инъекционным препаратам, и я не был уверен, есть ли заметное функциональное преимущество в использовании одного над другим. Или они сводятся к одному и тому же.
Скажем, например, мой модуль определяется следующим образом:
var app = angular.module('MyModule', ['some.Third.Party.Module']);
Теперь учтите, что в стороннем модуле есть фабрика с переменной, которую нужно установить. Это может быть достигнуто следующим образом:
app.run(['some.Third.Party.Module.Factory', function (theFactory) {
theFactory.someVariable = 'foo';
}]);
Альтернативный метод будет:
app.run(function ($injector) {
var theFactory = $injector.get('some.Third.Party.Module.Factory');
theFactory.someVariable = 'foo';
});
Один метод лучше, чем другой? Может быть, есть третий вариант, который я еще не рассмотрел?
3 ответа
На самом деле вы используете три разных метода (насколько мне известно), Angular обеспечивает внедрение зависимостей.
Angular может идентифицировать зависимость исключительно через имя параметра функции. Вы делаете это здесь, когда вы вводите $injector
,
app.run(function ($injector) { ... });
Вышеприведенное описание является быстрым и простым для разработки, но вы можете столкнуться с проблемами при минимизации кода, поскольку имена переменных могут изменяться.
Для производства и, как правило, хорошей практикой в разработке является использование аннотаций, как вы уже использовали во втором примере кода для some.Third.Party.Module.Factory
,
app.run(['$injector', function ($injector) { ... }]);
Третий способ, который я знаю, это использовать $injector
непосредственно. Это полезно для модульного тестирования и, если, возможно, вы хотите условно переключить, какая зависимость вводится. Он обеспечивает динамическую аннотацию, а не статическую.
Я думаю, что есть два случая, когда вам нужно получить сервис / фабрику / что угодно через $ инжектор:
1) у вас круговая зависимость, но вы уверены, что все будет хорошо.
2) вам нужно получить что-то из "углового мира" извне.
upd: также интересный случай, представленный @Explosion Pills.
Первое фактически является сокращением для второго, но имейте в виду, что ссылки $injector
напрямую вызовет проблемы, если вы уменьшите код, так как эта переменная будет переименована. Ваше первое использование защищено от минификации.
Я обычно придерживаюсь первого использования, но вы также можете использовать $inject
аннотация вот так:
var MyController = function($scope, greeter) {
// ...
}
MyController.$inject = ['$scope', 'greeter'];
someModule.controller('MyController', MyController);
Это имеет смысл, если вы хотите добавить свойства MyController
прототип и до сих пор используют его в качестве определения контроллера.
Я действительно не уверен в сценарии, где вам нужно будет использовать $injector
непосредственно, если вы не делали что-то очень модное.
Также имейте в виду разницу между run
а также config
методы. Последний позволяет вам использовать провайдеров, которые позволяют вам настроить службы, используемые в run
метод (и когда они вводятся).