我可以将服务注入指令吗?

Exc*_*ion 233 angularjs

我正在尝试将服务注入到如下的指令中:

 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;
            }
        }
 });
Run Code Online (Sandbox Code Playgroud)

但这让我错了Unknown provider: myDataProvider.有人可以查看代码并告诉我,如果我做错了什么?

gre*_*ian 386

你可以对Directives进行注入,它看起来就像在其他任何地方一样.

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

  • 我认为这是一个更好的解决方案,因为它甚至可以在缩小代码后工作. (13认同)
  • 在指令中注入$ compile的任何特殊原因?它似乎没有在任何地方使用. (6认同)
  • 我必须在return {}之前添加'_myData = myData',然后在链接函数中将对象引用为_myData. (5认同)
  • 如果要在指令调用之外创建链接函数,是否有注入解决方案? (3认同)

gan*_*raj 19

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

它确实工作正常.我不确定你在做什么是错的.这是一个工作的插件.

http://plnkr.co/edit/M8omDEjvPvBtrBHM84Am

  • 我不确定我同意你的"耦合"评论.我们已经将控制器和服务全局耦合 - 我们无法在运行时以编程方式替换服务的实现.这意味着单个控制器获得单个服务.但是 - 指令在页面上的每个标记都有隔离配置,因此我们可能会为不同的指令实例启用不同的服务.在我看来,这种情况不那么脱钩了. (13认同)
  • 我刚刚发现了一些东西:如果在函数参数中定义一个注入,`function($ location){...`但实际上并没有在函数内部引用`$ location`,AngularJS将不执行注入.您唯一一次注意到此行为是在调试器内部. (3认同)

Tyr*_*son 10

您还可以使用$ inject服务来获得您喜欢的任何服务.如果我提前不知道服务名称但知道服务接口,我觉得很有用.例如,将表插入ngResource端点的指令或与任何api端点交互的通用删除记录按钮.您不希望为每个控制器或数据源重新实现表指令.

template.html

<div my-directive api-service='ServiceName'></div>
Run Code Online (Sandbox Code Playgroud)

my-directive.directive.coffee

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

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

例如:

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

我发现这种技术在制作与API端点交互的元素时非常有用.