简体   繁体   English

angularjs $作用域和控制器

[英]angularjs $scope and controller

I'm new to angular, I've read couple of articles on scope and controllers but I think I still don't get it. 我对angular并不陌生,我已经阅读了几篇关于范围和控制器的文章,但我认为我仍然不明白。

Lets say we have a code 可以说我们有一个代码

    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);
        };
    });

and markup: 和标记:

<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>

Everything works when I use "ng-click="show = !show" in the ng-show. But when I use toggle() insted it doesn't. My question is how to change the code to make method toggle() work ? How to access the actuall scope than I'm operating in in the controller ? Should I use ng-controller="myCtrl" on each li tag ? Should I have a controller for each scope that is created by the directives in my markup ? What is the best practise here ? 当我在ng-show中使用“ ng-click =” show =!show“时,一切正常。但是,当我使用toggle()插入时,它却没有。我的问题是如何更改代码以使方法toggle()工作?如何访问比我在控制器中操作的实际作用域更大的范围?我应该在每个li标签上使用ng-controller =“ myCtrl”吗?我应该为标记中的指令所创建的每个范围都拥有一个控制器吗?最佳做法是什么?

The reason that things seem strange is that ngRepeat uses an isolate scope. 事情看起来很奇怪的原因是ngRepeat使用隔离范围。 That means it creates a new child scope off of the parent. 这意味着它将从父级创建一个新的子级。

When you use show = !show , you are creating a show value on that child scope. 当使用show = !show ,您将在该子作用域上创建一个show值。

When you use toggle , you are trying to call a method on the scope that doesn't exist. 使用toggle ,您尝试在不存在的作用域上调用方法。

You could try calling $parent.toggle() on the click event, but that will set the show value on the parent scope rather than individual rows. 您可以尝试在click事件上调用$parent.toggle() ,但这将在父作用域而不是单个行上设置show值。

What's being said is true, the show inside the ngRepeat is different from the show in myCtrl . 什么正在说的是真的,在show里面ngRepeat是从不同的showmyCtrl However, even if it weren't, there's only one variable show in myCtrl , so every item would be hidden and shown together when toggling. 但是,即使不是, myCtrl也只show一个变量,因此切换时每个项目都将被隐藏并一起显示。

If you want to toggle individual rows, they each need their own flag. 如果要切换单个行,则每个行都需要有自己的标志。 There are several ways to accomplish this. 有几种方法可以完成此操作。 But to avoid too much logic in the view, and to avoid the use of $parent , one way would be to use the controller as syntax, and keep a list of show flags, taking advantage of the fact that ngRepeat supplies the array index as $index . 但是,为了避免视图中的逻辑过多以及避免使用$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);
    };
});

Then the view: 然后查看:

<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>

You could also use an array of objects if you plan to do something complicated where keeping track of two arrays would be difficult. 如果您打算做一些很难跟踪两个数组的复杂操作,则也可以使用对象数组。 Something like: 就像是:

myCtrl.array = [
  {val: 1, show: false},
  {val: 2, show: false},
  {val: 3, show: false},
];

Then the toggle function would be: 那么切换功能将是:

myCtrl.toggle = function(obj){
  obj.show = !obj.show;
};

and the view: 和视图:

<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>

Edit: here's a plunkr for each. 编辑:这是每个人的朋克。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM