在指令的控制器内调用一个函数

时间:2014-12-24 05:06:24

标签: javascript angularjs

是否可以从外部调用directive控制器中定义的方法。

<div ng-controller="MyCtrl">
    <map></map>
    <button ng-click="updateMap()">call updateMap()</button>
</div>

app.directive('map', function() {
    return {
        restrict: 'E',
        replace: true,
        template: '<div></div>',
        controller: function(){
           $scope.updateMap = function(){
              //ajax call here.
           }
        },
        link: function($scope, element, attrs) {
            $scope.updateMap();
            //do some dom transformation
        }
    }
});

我想从我的视图中调用方法updateMap()

3 个答案:

答案 0 :(得分:1)

如果在控制器上公开函数而不是作用域,则可以在父作用域上公开控制器,例如:

    controller: function($scope, $element, $attrs){
       // Verify this. The controller has to be added to the parent scope, if the directive itself is creating a scope
       $scope.$parent[$attrs["name"]]=this;   

       this.updateMap = function(){
          //ajax call here.
       }
    },

现在在主控制器中,您将能够访问控制器:

<button ng-click="myMap.updateMap()">call updateMap()</button>

这与ng-model暴露其控制器的方式类似。将控制器视为指令的API。

答案 1 :(得分:0)

根据需要从控制器访问函数是不好的做法。但是你仍然可以将updateMap函数绑定到$ rootScope,因此它可以全局使用,并仍然将当前作用域作为参数传递给它。

例如,

$rootScope.updateMap = function($scope) {
  // use the scope to do the manipulation
}

<div ng-controller="MyCtrl">
 <map></map>
 <button ng-click="updateMap(this)">call updateMap()</button>
</div>

这里在updateMap函数中传递'this'将引用元素被包装的范围。在上面的例子中,'this'将引用MyCtrl的$ scope

答案 2 :(得分:0)

我建议两种选择。一个简单的选择是使用事件:

<div ng-controller="MyCtrl">
    <map></map>
    <button ng-click="updateMap()">call updateMap()</button>
</div>

app.directive('map', function() {
    return {
        restrict: 'E',
        replace: true,
        template: '<div></div>',
        controller: function(){
           $scope.updateMap = function(){
              //ajax call here.
           }
        },
        link: function($scope, element, attrs) {
            $scope.$on('my.update.map.event', $scope.updateMap);
        }
    }
});

app.controller('MyCtrl', function ($scope) {
    $scope.updateMap = function () {
        $scope.$broadcast('my.update.map.event');
    };
});

这不是一个糟糕的解决方案。你没有污染根范围(@Krishna的答案),你的地图指令并没有在控制器的范围内添加任意值(@ Chandermani的回答)。

如果你想避免事件,另一个选择是使用controllerAs语法来公开你的map指令的控制器。

<div ng-controller="MyCtrl">
    <map controller="mapController"></map>
    <button ng-click="mapController.updateMap()">call updateMap()</button>
</div>

app.directive('map', function() {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            'controller': '=?'
        },
        template: '<div></div>',
        //controllerAs creates a property named 'controller' on this 
        //directive's scope, which is then exposed by the 
        //'scope' object above
        controllerAs: 'controller',
        controller: function(){
           this.updateMap = function(){
              //ajax call here.
           }
        },
        link: function($scope, element, attrs, ctrl) {
            ctrl.updateMap();
        }
    }
});

这与@ Chandermani的答案类似,但是你的控制器和你的指令之间的耦合更明确。我可以从视图中看出map指令暴露了它的控制器,并且它将在MyCtrl的范围内被称为mapController。

(我发现了这个想法here)。