164

我有一个例子 angularJS

<div ng-controller="testCtrl">

<test color1="color1" updateFn="updateFn()"></test>
</div>
 <script>
  angular.module('dr', [])
.controller("testCtrl", function($scope) {
    $scope.color1 = "color";
    $scope.updateFn = function() {
        alert('123');
    }
})
.directive('test', function() {
    return {
        restrict: 'E',
        scope: {color1: '=',
                updateFn: '&'},
        template: "<button ng-click='updateFn()'>Click</button>",
        replace: true,
        link: function(scope, elm, attrs) { 
        }
    }
});

</script>
</body>

</html>

我希望当我单击按钮时,会出现警报框,但什么也没有显示。

谁能帮我?

4

7 回答 7

249

要从隔离范围指令内部调用父范围内的控制器函数,请使用dash-separatedHTML 中的属性名称,如 OP 所说。

此外,如果您想向函数发送参数,请通过传递对象来调用函数:

<test color1="color1" update-fn="updateFn(msg)"></test>

JS

var app = angular.module('dr', []);

app.controller("testCtrl", function($scope) {
    $scope.color1 = "color";
    $scope.updateFn = function(msg) {        
        alert(msg);
    }
});

app.directive('test', function() {
    return {
        restrict: 'E',
        scope: {
            color1: '=',
            updateFn: '&'
        },
        // object is passed while making the call
        template: "<button ng-click='updateFn({msg : \"Hello World!\"})'>
            Click</button>",
        replace: true,        
        link: function(scope, elm, attrs) {             
        }
    }
});

Fiddle

于 2013-08-22T11:01:09.030 回答
164

也许我遗漏了一些东西,但是尽管其他解决方案确实调用了父作用域函数,但无法从指令代码传递参数,这是因为使用固定参数update-fn进行调用updateFn(),例如{msg: "Hello World"}. 稍作更改允许指令传递参数,我认为这更有用。

<test color1="color1" update-fn="updateFn"></test>

请注意,HTML 传递的是函数引用,即不带()括号。

JS

var app = angular.module('dr', []);

app.controller("testCtrl", function($scope) {
    $scope.color1 = "color";
    $scope.updateFn = function(msg) {        
        alert(msg);
    }
});

app.directive('test', function() {
    return {
        restrict: 'E',
        scope: {
            color1: '=',
            updateFn: '&'
        },
        // object is passed while making the call
        template: "<button ng-click='callUpdate()'>
            Click</button>",
        replace: true,        
        link: function(scope, elm, attrs) {       
          scope.callUpdate = function() {
            scope.updateFn()("Directive Args");
          }
        }
    }
});

因此,在上面,HTML 正在调用本地范围callUpdate函数,然后该函数从父范围“获取”updateFn 并使用指令可以生成的参数调用返回的函数。

http://jsfiddle.net/mygknek2/

于 2015-03-13T01:33:02.560 回答
39

在您的“测试”指令 Html 标记中,函数的属性名称不应为驼峰式,而是基于破折号。

所以 - 而不是:

<test color1="color1" updateFn="updateFn()"></test>

写:

<test color1="color1" update-fn="updateFn()"></test>

这是 Angular 区分指令属性(例如 update-fn 函数)和函数的方法。

于 2014-01-29T14:39:05.030 回答
10

如何通过双向绑定传递控制器功能?然后,您可以在指令中以与常规模板完全相同的方式使用它(为简单起见,我删除了不相关的部分):

<div ng-controller="testCtrl">

   <!-- pass the function with no arguments -->
   <test color1="color1" update-fn="updateFn"></test>
</div>

<script>
   angular.module('dr', [])
   .controller("testCtrl", function($scope) {
      $scope.updateFn = function(msg) {
         alert(msg);
      }
   })
   .directive('test', function() {
      return {
         scope: {
            updateFn: '=' // '=' bidirectional binding
         },
         template: "<button ng-click='updateFn(1337)'>Click</button>"
      }
   });
</script>

我遇到了这个问题,因为我尝试了上面的方法,但不知何故它不起作用。现在它完美地工作了。

于 2017-04-21T14:42:42.223 回答
6

使用破折号和小写的属性名称(如其他答案所说):

 <test color1="color1" update-fn="updateFn()"></test>

并在指令范围内使用“=”而不是“&”:

 scope: { updateFn: '='}

然后您可以像使用任何其他函数一样使用 updateFn:

 <button ng-click='updateFn()'>Click</button>

给你!

于 2016-06-28T20:15:06.663 回答
4

我不得不使用“=”绑定而不是“&”,因为那不起作用。奇怪的行为。

于 2017-08-21T09:11:45.417 回答
0

@JorgeGRC 感谢您的回答。但有一件事,“也许”部分非常重要。如果您确实有参数,则必须在模板中也包含它/它们,并确保指定您的本地人,例如updateFn({msg: "Directive Args"}.

于 2019-07-12T08:15:00.847 回答