【问题标题】:AngularJS - Error while manually using injector to inject a serviceAngularJS - 手动使用注入器注入服务时出错
【发布时间】:2017-02-03 09:00:22
【问题描述】:

我在尝试手动使用 angular.injector 注入正在打开对话框的服务时遇到问题,而该对话框又在其模板中使用了一个指令,该指令使用动态模板。

我在控制台中遇到的错误是:

1:未知提供者:$rootElementProvider

2:找不到指令“ngInclude”所需的控制器“ngInclude”!

这里是plunker demonstrating the problem

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

我还尝试构建 url 并将其指定为指令属性并从 templateUrl 函数访问它,但在这种情况下它也失败了,因为我收到的值只是变量的名称,而不是内容。

如果我避免通过 angular.injector 注入服务,代码可以工作,但是由于应用程序的性质,我无法避免它,此外,我有兴趣了解此错误的背后原因是什么,如果有人好心解释一下这件事。

【问题讨论】:

  • 你想在你的指令中访问“customSvc”服务,对吧?
  • 我已经通过 angular.injector 函数访问它并且它可以工作,问题出在 sampleDirective 中,因为在那里,ng-include 不起作用
  • 在sampleDirective中,为什么你在模板中使用ng-include,而你所包含的文件没有扩展名?template: "
    " , 使用 templareUrl:"sampleLinkTemplate.html"
  • 因为它使用了链接函数中设置的范围内的变量值。这是一种基于作用域中存在的变量使用“动态模板”的方式

标签: angularjs angularjs-injector


【解决方案1】:

解决办法是通过以下方式注入服务:

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

这是工作的plunker

【讨论】:

    【解决方案2】:

    在您的 gedContextMenu.js 文件中,进行以下更改

    注入pluginApp

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

    gedContextMenu 菜单指令中注入服务customSvc

    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);
    
            }
          });
        }
      }
    }]);
    

    【讨论】:

    • 就像我在问题中所说的那样,如果我绕过注射器的手动使用,它可以工作,但我不能在我的应用程序中这样做,因为 actions.js 是动态加载的,我没有在 gedContextMenu 指令级别知道它将使用或不使用哪些服务。我发布的 plunker 只是对问题的简化。无论如何,我仍然需要手动使用 angular.injector 或了解是否由于某些限制而无法使用
    猜你喜欢
    • 2015-11-03
    • 2013-05-28
    • 2016-11-02
    • 1970-01-01
    • 1970-01-01
    • 2016-12-09
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    相关资源
    最近更新 更多