【问题标题】:AngularJS: variable in ng-repeat without $scope is in its local scope?AngularJS:没有 $scope 的 ng-repeat 中的变量在其本地范围内吗?
【发布时间】:2013-10-09 18:48:03
【问题描述】:

代码如下:

<ul>
  <li ng-repeat="i in items" ng-class="{'red': click}">
    <span ng-click="click = !click">{{i}}</span>
  </li>
</ul>

<ul>
  <li ng-repeat="j in items" ng-class="{'red': f_click}">
    <span ng-click="fun_click($index)">{{j}}</span>
  </li>
</ul>

f_clickfun_click 函数的变化。

$scope.fun_click = (idx) ->
    $scope.f_click = !$scope.f_click

完整代码: http://plnkr.co/edit/Zmoqbv?p=preview

我想知道第一个列表中的变量 click 是每个 ng-repeat 元素的局部变量吗?
效果如何?

如何使第二个列表中的f_clickclick 一样工作?
似乎 $scope.f_click 是 ng-controller 中唯一的一个变量。


更新:

我想我只是做错了。
我不应该在“视图”中写东西。

在视图中只读;
在 Controller 中只写。
http://www.jacopretorius.net/2013/07/angularjs-best-practices.html

【问题讨论】:

  • 谢谢你们!我读了你所有的答案,我学到了很多!非常感谢大家!我希望有一天我能帮助别人。

标签: javascript variables angularjs coffeescript


【解决方案1】:

第一个 ngRepeat 有效而第二个无效的原因是 ngRepeat 为每个项目创建了一个范围。换句话说,items 中的每个项目都有一个 click 变量的实例,并且通过在 ngClick 中切换 click 变量,您实际上是在使用私有实例。在第二个示例中,您使用控制器的$scope 访问f_click,它是 ngRepeat 范围的父级,因此更改会传播到所有子范围。

因此,解决您的问题的一个简单方法是将在 ngRepeat 中创建的 f_click 实例传递给您的函数:

// Script
$scope.fun_click = (toggle) ->
    return !toggle

// HTML
<span ng-click="f_click=fun_click(f_click)">{{j}}</span>

如果您希望保持$scope 中的状态,可以使用字典来跟踪每个$index 的状态:

// Script
$scope.form_status = {}
$scope.fun_click = (index) ->
    $scope.form_status[index] = !$scope.form_status[index]

// HTML
<li ng-repeat="j in items" ng-class="{'red': form_status[$index]}">
    <span ng-click="fun_click($index)">{{j}}</span>
</li>

这里是更新的 plunker:http://plnkr.co/edit/w6RLed?p=preview

【讨论】:

    【解决方案2】:

    如何让第二个列表中的 f_click 像点击一样工作

    据我所知,你不能。从您的第一个示例中,click 没有引用任何范围。

    f_click 指的是特定范围,任何更改都分布在所有元素上(也就是循环中的所有项目上)

    您可以为每个值提供标志,例如:

    $scope.items2 = [
    {'name': 'Google','value':false},
    {'name': 'Apple','value':false},
    {'name': 'Yahoo','value':false},
    {'name': 'IBM','value':false},
    ];
    
     $scope.fun_click = (item) ->
       item.value = !item.value;
    

    HTML

     <ul>
      <li ng-repeat="j in items2" ng-class="{'red': j.value}">
        <span ng-click="fun_click(j)">{{j.name}}</span>
      </li>
    </ul>
    

    Plunker

    【讨论】:

    • 你甚至不需要给他们默认的value: false,你知道:plnkr.co/edit/qgXbDp?p=preview
    • @Cherniv 你是对的 100%,但它使代码可读。 2 个月后,其他程序员需要花时间了解为什么它是错误的。就像在 Java 中输入 if(flag)if(flag==true)
    【解决方案3】:

    ng-repeat 为每次迭代创建一个范围。 click 变量存在于每个 ng-repeat 范围内,换句话说,它是私有的。如果您将{{click}} 放在&lt;body ng-controller="MainCtrl"&gt; 之后但ng-repeat 之前,它将不会显示任何内容,因为click 存在于内部范围中。

    另一方面,f_click 位于MainCtrl 的范围内,这是ng-repeats 的 范围。改变它的函数 (fun_click) 也存在于父作用域中。 ng-repeat 范围继承此变量的单个实例,从而观察到的行为。

    要使f_clickclick 一样工作,您必须将其设为私有到每个ng-repeat 迭代的范围。一种解决方案是在控制器inside ng-repeat 中定义f_clickfun_click()。其他解决方案也是可能的。

    【讨论】:

    • "ng-repeat 为每次迭代创建一个范围。"谢谢! @Nikos 我会更深入地阅读文档。
    猜你喜欢
    • 2013-07-23
    • 2018-08-12
    • 2016-11-28
    • 1970-01-01
    • 2014-12-12
    • 1970-01-01
    • 1970-01-01
    • 2013-03-15
    • 2015-11-06
    相关资源
    最近更新 更多