我可以在AngularJS的指令中注入服务吗?


234

我试图将服务注入如下指令:

 var app = angular.module('app',[]);
 app.factory('myData', function(){
     return {
        name : "myName"
     }
 });
 app.directive('changeIt',function($compile, myData){
    return {
            restrict: 'C',
            link: function (scope, element, attrs) {
                scope.name = myData.name;
            }
        }
 });

但这给我返回了一个错误Unknown provider: myDataProvider。有人可以调查一下代码,并告诉我是否做错了什么?

Answers:


388

您可以对指令进行注入,看起来就像在其他地方一样。

app.directive('changeIt', ['myData', function(myData){
    return {
        restrict: 'C',
        link: function (scope, element, attrs) {
            scope.name = myData.name;
        }
    }
 }]);

13
我认为这是一个更好的解决方案,因为即使在缩减代码后也可以使用。
czerasz

5
我必须在return {}之前添加'_myData = myData',然后在链接函数内部将对象引用为_myData。
Jelling 2013年

谢谢@耶林。我必须做同样的事情。我想知道是否有人可以告诉我们为什么...?
sfletche 2014年

6
在指令中注入$ compile的任何特殊原因?它似乎没有在任何地方使用。
2015年

4
如果要在指令调用之外创建链接函数,是否有注入解决方案?
ThinkBonobo

19

将指令定义从更改app.moduleapp.directive。除此之外,一切看起来还不错。 顺便说一句,您很少需要将服务注入指令中。如果要将服务(通常是数据源或模型)注入到指令(属于视图的一部分)中,则将在视图和模型之间建立直接耦合。您需要通过使用控制器将它们连接在一起来将它们分开。

它确实工作正常。我不确定您在做什么,这是错误的。这是一个工作原理。

http://plnkr.co/edit/M8omDEjvPvBtrBHM84Am


您能提供一个例子吗
例外

@Exception可以将代码放在小提琴中吗?我可以看看为什么您的代码无法正常工作,并可能会帮助您修复它。
ganaraj

@Exception添加了一个工作代码,显示了代码的运行情况。
ganaraj 2013年

3
我刚刚发现了一些东西:如果在函数参数中定义注入,function($location) { ...但实际上未$location在函数内部引用,AngularJS将不会执行注入。您唯一会注意到此行为的时间是在调试器内部。
Walter Stabosz

13
我不确定我是否同意你的“耦合”评论。我们已经在全局范围内耦合了控制器和服务-我们无法在运行时以编程方式替换服务的实现。这意味着单个控制器将获得单个服务。但是-伪指令对页面上的每个标签进行了隔离配置,因此有可能我们为不同的伪指令实例启用了不同的服务。在我看来,这种联系较少。
Guy Mograbi

11

您还可以使用$ inject服务获取所需的任何服务。如果我不提前知道服务名称但知道服务接口,我会发现它很有用。例如,将表插入ngResource端点的指令或与任何api端点交互的通用delete-record按钮。您不想为每个控制器或数据源重新实现table指令。

template.html

<div my-directive api-service='ServiceName'></div>

my-directive.directive.coffee

angular.module 'my.module'
  .factory 'myDirective', ($injector) ->
    directive = 
      restrict: 'A'
      link: (scope, element, attributes) ->
        scope.apiService = $injector.get(attributes.apiService)

现在,您的“匿名”服务已完全可用。例如,如果它是ngResource,则可以使用标准的ngResource接口获取数据

例如:

scope.apiService.query((response) ->
  scope.data = response
, (errorResponse) ->
  console.log "ERROR fetching data for service: #{attributes.apiService}"
  console.log errorResponse.data
)

我发现在制作与API端点进行交互的元素时,该技术非常有用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.