如果我有兩個不同的指令與孤立範圍,並且他們共享一個控制器,他們不應該共享控制器的$scope
?
實際上,我有以下情形:
- 我打電話到服務器並通過它的一些參數,讓我們稱之爲
x
和y
。 - 的服務器或者返回一些數據,或者返回null表明該數據不可用。
- 如果返回數據,我需要顯示一個按鈕;如果用戶單擊該按鈕,它將在獨立的div中顯示數據。
- 如果數據不回來,我不顯示的按鈕。
我一直在努力實現這個爲一組鏈接指令。我試圖這樣做,因爲這個「組件」將在應用程序中重複使用多次,並且我試圖在兩個指令中執行此操作,因爲我找不出任何其他方式來創建單個指令控制兩個不同的元素。
除了有很多,他們需要鏈接x
和y
值。所以,如果我有特別的x
和y
一個按鈕,然後點擊它只會切換使用相同x
和y
值的顯示區域的知名度。有效地,給定視圖將具有不同的x
和y
值。
無論如何,我有一個潛在的有效的解決方案,但我似乎有與共享的範圍問題。當我點擊按鈕時,我有記錄語句正確地表明我們觸發了「顯示」邏輯。但是div的ng-if
中的日誌語句始終將相同的邏輯評估爲false,並且不會顯示。
我的解決辦法是在三個部分:
- 一種用於按鈕
- 一種用於「展示」
- 控制器,該控制器由兩個
我共享指令指令有一個微不足道的工作示例,我將在下面分享。在這篇文章的末尾還有一個Plunkr網址。
下面是HTML。中間的<p>
標籤僅用於說明兩個指令在物理上不相鄰。
<trigger x="apple" y="2" ></trigger>
<p>Some unrelated dom content...</p>
<display x="apple" y="2"></display>
這是trigger
指令,它是按鈕:
app.directive("trigger", function() {
return {
restrict: "E",
scope: {
x : "@",
y : "@"
},
transclude: false,
template: "<button ng-if='hasCalculation(x,y)' ng-click='toggle()'>Trigger x={{x}} & y={{y}}</button>",
controller: 'testController',
link: function(scope) {
scope.doSomeWork();
}
};
});
這是display
指令,這是爲了顯示數據時由按鈕切換:
app.directive("display", function() {
return {
restrict: 'E',
scope: {
x : '@',
y : '@'
},
require: '^trigger',
transclude: false,
controller: 'testController',
template: "<p ng-if='shouldShow(x,y)'>{{getCalculation(x,y)}}</p>"
};
});
這是共享控制器,testController
:
app.controller("testController", ["$scope", function($scope) {
$scope.shouldShow = [[]];
$scope.calculatedWork = [[]];
$scope.doSomeWork = function() {
var workResult = "We called the server and calculated something asynchonously for x=" + $scope.x + " and y=" + $scope.y;
if(!$scope.calculatedWork[$scope.x]) {
$scope.calculatedWork[$scope.x] = [];
}
$scope.calculatedWork[$scope.x][$scope.y] = workResult;
};
$scope.hasCalculation = function(myX, myY) {
var xRes = $scope.calculatedWork[myX];
if(!xRes) {
return false;
}
return $scope.calculatedWork[myX][myY]
}
$scope.toggle = function() {
if(!$scope.shouldShow[$scope.x]) {
$scope.shouldShow[$scope.x] = [];
}
$scope.shouldShow[$scope.x][$scope.y] = !$scope.shouldShow[$scope.x][$scope.y];
console.debug("Showing? " + $scope.shouldShow[$scope.x][$scope.y]);
}
$scope.isVisible = function(myX, myY) {
console.debug("Checking if we should show for " + myX + " and " + myY);
var willShow;
if(!$scope.shouldShow[myX]) {
willShow = false;
} else {
willShow = $scope.shouldShow[myX][myY];
}
console.debug("Will we show? " + willShow);
return willShow;
}
$scope.getCalculation = function(myX, myY) {
if(!$scope.calculatedWork[myX]) {
return null;
}
return $scope.calculatedWork[myX][myY];
}
}]);
這裏是Plunkr。
如果您轉到Plunkr,您會看到正確呈現的觸發按鈕。如果單擊該按鈕,您將看到toggle()
方法正確地將shouldShow
的值翻轉爲與之前相反的值(該方法中有一個控制檯調試語句顯示其結果)。您還將看到isVisible
方法的重新評估,該方法確定顯示屏是否應顯示 - 此總是返回false。
我認爲這與我保存相對於$scope
的數據和可見性狀態有關。我對此的理解是,每條指令都有自己的$scope
,但由於它們共享一個控制器,不應該共享那控制器的$scope
?