如果我有两个不同的指令与孤立范围,并且他们共享一个控制器,他们不应该共享控制器的$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
?