我是棱角分明的新手,我已经阅读了几篇关于范围和控制器的文章,但我认为我仍然没有得到它。
让我们说我们有一个代码
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope) {
$scope.array = [1,2,3];
$scope.show = false;
$scope.toggle = function (){
$scope.show = !$scope.show;
console.log($scope.show);
};
});
和标记:
<body ng-app="myApp">
<ul ng-controller="myCtrl">
<li ng-repeat="n in array">
<a href="#" ng-click="show = !show">Click here to show</a>
<span ng-show="show">Something to show</span>
</li>
</ul>
</body>
当我在ng-show中使用“ng-click =”show =!show“时,一切都有效。但是当我使用toggle()时,它没有。 我的问题是如何更改代码以使方法切换()工作? 如何访问实际范围而不是我在控制器中操作? 我应该在每个li标签上使用ng-controller =“myCtrl”吗? 我是否应该为我的标记中的指令创建的每个范围都有一个控制器? 这里的最佳做法是什么?
答案 0 :(得分:0)
事情看起来很奇怪的原因是ngRepeat
使用了隔离范围。这意味着它会从父级创建一个新的子范围。
使用show = !show
时,您将在该子范围上创建show
值。
当您使用toggle
时,您正试图在不存在的范围内调用方法。
您可以尝试在click事件上调用$parent.toggle()
,但这会在父作用域而不是单个行上设置show
值。
答案 1 :(得分:0)
所说的是真的,show
中的ngRepeat
与show
中的myCtrl
不同。但是,即使不是,show
中只有一个变量myCtrl
,因此切换时每个项目都会被隐藏并显示在一起。
如果要切换单个行,则每个行都需要自己的标志。有几种方法可以实现这一目标。但是为了避免在视图中使用太多逻辑,并避免使用$parent
,一种方法是使用controller as
语法,并保留一个显示标志列表,利用以下事实: ngRepeat将数组索引提供为$index
。
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function() {
var myCtrl = this;
myCtrl.array = [1,2,3];
myCtrl.show = [false, false, false];
myCtrl.toggle = function (index){
myCtrl.show[index] = !myCtrl.show[index];
console.log(myCtrl.show);
};
});
然后是观点:
<body ng-app="myApp">
<ul ng-controller="myCtrl as ctrl">
<li ng-repeat="n in ctrl.array">
<a href="#" ng-click="ctrl.toggle($index)">Click here to show</a>
<span ng-show="ctrl.show[$index]">Something to show</span>
</li>
</ul>
</body>
如果你计划做一些复杂的事情,那么你也可以使用一个对象数组,这样就很难跟踪两个数组。类似的东西:
myCtrl.array = [
{val: 1, show: false},
{val: 2, show: false},
{val: 3, show: false},
];
然后切换功能将是:
myCtrl.toggle = function(obj){
obj.show = !obj.show;
};
和视图:
<body ng-app="myApp">
<ul ng-controller="myCtrl as ctrl">
<li ng-repeat="n in ctrl.array">
<a href="#" ng-click="ctrl.toggle(n)">Click here to show</a>
<span ng-show="n.show">Something to show</span>
</li>
</ul>
</body>
修改强> 这是每个人的傻瓜。