2015-02-05 68 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', 
    }; 
}) 

你連線了同一個控制器的指令作爲母,這是覆蓋所有你想要的屬性通過分離範圍傳遞:

相關問題