AngularJS指令与控制器耦合时不能传入不同的函数

AngularJS can't pass in different function when directive coupled with controller

我有一个指令,我想将其作为一个组件与控制器紧密耦合。我假设我通过显式传递我的函数来遵循最佳实践,即使我声明要使用控制器也是如此。这是一个例子:

app.js

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

app

 .controller('myCtrl', function($scope) {
   $scope.output = '';
   $scope.foo = function () {
     $scope.output = 'foo';
   }
   $scope.bar = function () {
     $scope.output = 'bar';
   }

 })

.directive('myDirective', function() {
  return {
    scope: {
      output: '=',
      foo: '&',
    },
    templateUrl: 'template.html',
    replace: true,
    controller: 'myCtrl',
  };
})

template.html

<div>
  <button ng-click="foo()">Click Foo</button>
  <p>You clicked: <span style="color:red">{{output}}</span></p>
</div>

index.html

<body>
  <my-directive
   output="output"
   foo="bar()">  <!-- pass in the *bar* function instead of the *foo* function -->
  </my-directive>
</body>

Plunkr:http://plnkr.co/edit/Y4lhxuXbK9YbjAklR7v1?p=preview

在这里,即使我传入了 bar() 函数,但在单击按钮时输出为 'foo'。如果我通过在指令中注释掉 controller: 'myCtrl' 来解耦控制器,输出将变为 'bar'.

我想我可以声明控制器,但仍然可以自由地将我想要的函数传递给指令。如果指令只是查找控制器以找到它,那么显式传递这些函数似乎也有点多余(我可以不传递任何东西到指令中,它仍然有效)。

这在测试时尤其有问题,因为我想将自己的存根函数传递给指令,但目前我无法做到。

有什么方法可以实现我想要的,还是我做错了什么?

EDIT 我的意思是不在 HTML.

中声明控制器

当 运行 在指令中时,$scope 在调用控制器构造函数之前用输出和 foo 变量初始化。您的控制器实际上正在覆盖这些属性。

在您的控制器中进行简单检查

if(!$scope.foo)
{
    $scope.foo = function () {
    $scope.output = 'foo';
    }
}

会起作用。

PS。我假设你的例子是你问题的简化。如果不是,那么其他答案的建议就是简单地从指令中删除控制器是最好的方法。

删除指令上的 controller 属性:

.directive('myDirective', function() {
  return {
    scope: {
      output: '=',
      foo: '&',
    },
    templateUrl: 'template.html',
    replace: true,
    // controller: 'myCtrl',
  };
})

您正在将同一个控制器连接到指令作为父指令,这将覆盖您试图通过隔离范围传入的所有属性。控制器连接 两次 ,一次在父作用域上,然后在指令上再次连接。去掉这个可以让你传入函数bar(),不会被覆盖

这是Plunker Demonstration