2015-02-05 43 views
0

我有一个指令,我想与一个控制器作为一个组件紧密耦合。即使我宣布要使用控制器,我仍然认为我遵循了最佳做法,明确地传递了我的功能。下面是一个例子:当指令与控制器耦合时,AngularJS不能通过不同的功能

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> 

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

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

我以为我可以声明控制器,但仍然可以自由地传递我希望指令的功能。似乎明确地传递这些函数有点多余,如果该指令只是查找控制器来找到它(我可以不传递任何指令,它仍然工作)。

当测试我想将自己的存根函数传递给指令时,这是特别有问题的,目前我不能这样做。

是否有某种方法可以实现我想要的或者我正在做一些根本性错误?

任何帮助非常感谢。

编辑我的意思是没有在html中声明的控制器。

+0

您的指令和html使用相同的控制器?所以这两个功能都被定义了。只需从指令 – PSL 2015-02-05 21:23:44

+0

中删除'controller:'myCtrl','他们是?他们不会是MyCtrl的不同实例吗? – 2015-02-05 21:24:53

+0

是的,这实际上是我的错误。我想消除html中的'ng-controller',abd将指令中的控制器耦合起来。我仍然有同样的问题。 – 2015-02-05 21:35:49

回答

0

的指令取出controller财产。控制器连线两次,一次在父范围上,然后再次在指令上。删除这将允许您通过功能bar(),它不会被覆盖。

这是Plunker Demonstration

+0

Agh。我的错。我其实不想在那里有'ng-controller'。如果我删除它,我仍然想要在指令中耦合我的控制器,并获得相同的结果。 http://plnkr.co/edit/Y4lhxuXbK9YbjAklR7v1?p=preview – 2015-02-05 21:33:45

+0

在你的新例子中,'bar()'表达式不起作用,因为'bar'没有在父作用域上定义。但是,由于控制器将'foo'属性重写为另一个函数,因此您不会看到该结果。 – 2015-02-05 21:38:10

+0

DDO的'controller'属性和'scope'属性可能会有一些混淆。 “范围”属性将创建一个隔离范围,您可以在父范围中获取值或评估表达式。 'controller'属性只是通过该指令的作用域将控制器连接到该指令,而不创建父子作用域关系。 – 2015-02-05 21:42:01

0

在指令内部运行时,$ scope在调用控制器构造函数之前用output和foo变量进行初始化。你的控制器基本上覆盖了这些属性。

在控制器中一个简单的检查

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

会工作。

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

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

你连线了同一个控制器的指令作为母,这是覆盖所有你想要的属性通过分离范围传递:

相关问题