AngularJS — ошибка при ручном использовании инжектора для внедрения службы

Я сталкиваюсь с проблемой при попытке вручную использовать angular.injector для внедрения службы, которая открывает диалог, который, в свою очередь, использует внутри своего шаблона директиву, которая использует динамический шаблон.

Ошибки, которые у меня есть в консоли:

1: Неизвестный провайдер: $rootElementProvider ‹- $rootElement ‹- $location ‹- $anchorScroll ‹- ngIncludeDirective ‹- $location

2: Контроллер ngInclude, требуемый директивой ngInclude, не найден!

Вот плункер, демонстрирующий проблему

var customSvc = angular.injector(['ng', 'pluginApp']).get("customSvc");
customSvc.testOpenDialog(100, scope);

Я также попытался создать URL-адрес и указать его как атрибут директивы и получить к нему доступ из функции templateUrl, но и в этом случае это не удается, потому что значение, которое я получаю, — это просто имя переменной, а не содержимое.

Если я избегаю внедрения службы через angular.injector, код работает, однако из-за характера приложения я не могу этого избежать, кроме того, мне интересно понять, в чем причина этой ошибки, если кто-то достаточно любезен, чтобы пролить свет на этот вопрос.


person Dragos    schedule 26.09.2016    source источник
comment
Вы хотите получить доступ к сервису customSvc в своей директиве, верно?   -  person random    schedule 26.09.2016
comment
Я уже обращаюсь к нему через функцию angular.injector, и он работает, проблема в sampleDirective, потому что там ng-include не работает   -  person Dragos    schedule 26.09.2016
comment
Почему в sampleDirective вы используете ng-include в шаблоне, а файл, который вы включаете, не имеет расширения?   -  person random    schedule 26.09.2016
comment
Потому что он использует значение переменной из области видимости, которая установлена ​​в функции ссылки. Это способ использования динамического шаблона на основе переменной, присутствующей в области видимости.   -  person Dragos    schedule 26.09.2016


Ответы (2)


Решение состоит в том, чтобы внедрить сервис следующим образом:

   var customSvc = angular.injector(['ng', 'pluginApp', 
      function($provide) {
        var $rootElement = angular.element(document.querySelector('body'));
        $provide.value('$rootElement', $rootElement);
      }]).get("customSvc");

Вот рабочий плункер

person Dragos    schedule 26.09.2016

В файле gedContextMenu.js внесите следующие изменения

Ввести pluginApp

angular.module('gedContextMenuApp', ['ui.bootstrap', 'mgcrea.ngStrap.popover','pluginApp']);

Добавьте сервис customSvc в директиву меню gedContextMenu,

angular.module('gedContextMenuApp').directive('gedContextMenu',['$log','$templateCache', '$uibModal', 'customSvc', function($log, $templateCache, $uibModal, customSvc) {
  return {
    restrict: 'AE',
    scope: {
      gedContextData: '='
    },
    template: "<button class='fa fa-cog' bs-popover data-template='{{popoverTemplate}}' data-auto-close='1' data-placement='bottom' data-animation='am-flip-x'></button>",
    controller: function($scope) {
      $scope.popoverTemplate = 'popoverTemplate.html';

      $scope.executePlugin = function($event, contextItem) {
        var propName = contextItem.action;
        $scope.contextItem = contextItem;
        $log.info('property name ' + propName + ' used to trigger event ', $event.type);
        $scope[propName] = $event;
      }

      $scope.click = function($event, contextItem) {
        $scope.executePlugin($event, contextItem);
      }
    },
    link: function(scope, element, attrs) {
        scope.$watch('openDialog', function(event) {
        if (event && event.type === 'click') {
          console.log(customSvc);
          // var customSvc = angular.injector(['ng', 'pluginApp']).get("customSvc");

          //angular.injector(['ng', function($provide) {
          //  var $rootElement = angular.element(document.querySelector('body'));
          //  $provide.value('$rootElement', $rootElement);
          //}]).invoke(function($injector) {
          //  var localRootElement = $injector.get('$rootElement');
          //});

          // customSvc.testOpenDialog(100, scope);
          //customSvc.testDirettivaConfirm(100, scope);

        }
      });
    }
  }
}]);
person random    schedule 26.09.2016
comment
Как я уже сказал в своем вопросе, если я обойду ручное использование инжектора, это сработает, но я не могу сделать это в своем приложении, потому что action.js загружается динамически, и я не знаю на уровне директивы gedContextMenu, какие службы он будет использовать или не использовать. Плункер, который я разместил, был просто упрощением проблемы. Несмотря на это, мне все еще нужно заставить его работать с ручным использованием angular.injector или понять, возможно ли это из-за некоторых ограничений. - person Dragos; 26.09.2016