【问题标题】:Using service inside directive?在指令内使用服务?
【发布时间】:2016-07-18 09:10:10
【问题描述】:

我正在学习如何创建自定义指令。

我的服务如下所示:

myApp.service('myService',function(){
    this.myFunction=function(myParam){
        // do something
    }
});

这是我的指令

myApp.directive('myDirective',function(myService){
    return {
        restrict: 'E',
        scope: {
          param: '=myParam',
        },
        template: '<button ng-click="myService.myFunction(param)">Do action</button>',
    }
});

在 HTML 中,当我使用 &lt;my-directive my-param="something"&gt;&lt;/my-directive&gt; 时,它会正确呈现为按钮。但是,当我单击它时,myService.myFunction 并没有被执行。

我想我做错了什么。有人可以给我一个方向吗? 我想这与指令的范围有关。

【问题讨论】:

    标签: javascript angularjs angularjs-directive


    【解决方案1】:

    该服务不能直接在模板中使用。您必须使用附加到指令的scope 的函数并从该函数中调用服务函数。

    myApp.directive('myDirective',function(myService){
        return {
            restrict: 'E',
            scope: {
              param: '=myParam',
            },
            template: '<button ng-click="callService(param)">Do action</button>',
            link: function(scope, element, attrs) {
                scope.callService = function() {
                    myService.myFunction();
                }
            }
        }
    });
    

    【讨论】:

    • 这显然有效,但特别是当你编写测试时,这个指令很难测试。当您在控制器中编写所有逻辑时,它变得更易于维护和测试。所以我总是建议为你的逻辑使用控制器而不是链接功能。
    【解决方案2】:

    它不起作用,因为在您的示例中,指令实际上并不知道myService 是什么。您必须显式注入它,例如:

    myApp.directive('myDirective', ['myService', function(myService){ ... }]);
    

    另请参阅此question 或此question

    【讨论】:

      【解决方案3】:

      您应该使用控制器来进行所有 DOM 修改。
      看到这个 plunkr:https://plnkr.co/edit/HbfD1EzS0av5BG6NgtIv?p=preview

      .directive('myFirstDirective', [function() {
        return {
          'restrict': 'E',
          'controller': 'MyFirstController',
          'controllerAs': 'myFirstCtrl',
          'template': '<h1>First directive</h1><input type="text" ng-model="myFirstCtrl.value">'
        };
      }
      

      【讨论】:

        【解决方案4】:

        您可以在控制器中注入服务,然后在模板中调用该函数:

        myService 注入控制器:

        myApp.controller("ctrl", function($scope, myService) {
            $scope.doService = function(myParam) {
                return myService.myFunction(myParam);
            };
        });
        

        调用模板内控制器的doService 方法:

        myApp.directive('myDirective',function(){
            return {
                restrict: 'E',
                scope: {
                  param: '=myParam',
                },
                template: '<button ng-click="doService(param)">Do action</button>',
            }
        });
        

        【讨论】:

        • -1。使用这种策略,您最终会得到一个非常紧密耦合的控制器/指令对。几乎不可能在其他任何地方使用该指令,除非以相同的目的定义完全相同的函数名称。指令旨在易于重用。
        猜你喜欢
        • 2013-05-26
        • 2015-06-15
        • 1970-01-01
        • 2016-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-14
        • 2015-04-19
        相关资源
        最近更新 更多