AngularJS:从具有隔离作用域的控制器中调用指令中的函数

AngularJS : Calling a function in a directive from a controller with isolated scope

本文关键字:控制器 指令 函数 调用 作用域 隔离 AngularJS      更新时间:2023-09-26

我有一个指令,本质上只是一个搜索框与多个参数。在控制器中,搜索功能需要访问一个名为getOptions()的函数,该函数用于获取搜索框设置。目前,我通过使用默认的scope: false并在指令中使用$scope.getOptions() = function()....来工作。

这里是一个示例代码片段(我前面没有代码所以我要用内存,这可能在语法上不正确,但它确实有效)

angular.module('example', [])
  .controller('Controller', ['$scope', function($scope) {
  function search() {
    //do something using $scope.getOptions()
  }
  // other functions that modify $scope.someParameter1 ....
  }])
  .directive('searchBox', function() {
    return {
      restrict: 'E',
      templateUrl: 'someurl.html'
      link: link
    };
    function link($scope) {
      $scope.someParameter1 = something;  // the default
      $scope.someParameter2 = something;  // the default
      $scope.getOptions() = function () {
        //do something with parameters
      }
    }
  });

然而,这是不好的做法,如果我在同一页面上有多个搜索框,它不起作用,所以我试图使用scope: {}使用一个孤立的范围。我可以保留控制器中的参数并将它们传递到getOptions()函数中,而不是依赖于$scope属性,但我不知道如何从控制器调用getOptions()。我不能从控制器中移动getOptions(),因为它调用了指令中的几个函数。

谢谢。

你*不能直接从隔离的作用域调用方法,但是我们可以反转我们的过程。我们将观察传递给指令的附加属性的变化。

指令的概念证明

.directive('box', function() {
    return {
        scope: {
            outsideScope: '=box'
        },
        template: 'directive box <br> isolated method: {{ wasCalled }}',
        restrict: 'A',
        link: function(scope, element, attrs) {
            scope.$watch('outsideScope', function(newValue, oldValue) {
                if(newValue !== oldValue) {
                    try {
                        scope[newValue](); // I'm going to call method with the name as passed string from controller
                    } catch(e) {
                        console.error(e);
                    }     
                }
            });
            scope.wasCalled = 'wasnt called';
            scope.isolateMethod = function() {
                scope.wasCalled = 'was called';
            }
        }
    }
});

控制器部分

controller('foo', function foo($scope) {
    $scope.changeOutsideScope = function() {
        $scope.outsideScope = 'isolateMethod';
    }
});

HTML

<div ng-controller="foo">
    <button ng-click="changeOutsideScope()">Call</button>
    <div class="directive" box="outsideScope"></div>
</div>

*你可以在测试中使用,因为Angular提供了.isolateScope()方法,你可以调用编译元素来检索指令的作用域。

jsfiddle: http://jsfiddle.net/krzysztof_safjanowski/P8ajy/