angularjs $ scope和controller

时间:2014-11-13 17:47:14

标签: javascript angularjs angularjs-scope

我是棱角分明的新手,我已经阅读了几篇关于范围和控制器的文章,但我认为我仍然没有得到它。

让我们说我们有一个代码

    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”吗? 我是否应该为我的标记中的指令创建的每个范围都有一个控制器? 这里的最佳做法是什么?

2 个答案:

答案 0 :(得分:0)

事情看起来很奇怪的原因是ngRepeat使用了隔离范围。这意味着它会从父级创建一个新的子范围。

使用show = !show时,您将在该子范围上创建show值。

当您使用toggle时,您正试图在不存在的范围内调用方法。

您可以尝试在click事件上调用$parent.toggle(),但这会在父作用域而不是单个行上设置show值。

答案 1 :(得分:0)

所说的是真的,show中的ngRepeatshow中的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>

修改 这是每个人的傻瓜。

http://plnkr.co/edit/sBhY00c5LU4YMeHlqjG7?p=preview

http://plnkr.co/edit/axO9sEB6oHQeDwIRLU4a?p=preview