AngularJS:在ng-repeat生成的范围中设置变量

时间:2013-07-24 08:34:27

标签: angularjs angularjs-scope angularjs-ng-repeat

如何访问ng-repeat生成的范围集?

我认为我的核心是这样一个事实,我不明白这种关系如何在a)传递给ng-repeat指令的对象集合和b)它生成的作用域集合之间起作用。我可以玩(a),ng-repeat范围观察和拾取,但我如何在范围本身设置变量(b)?

我的用例是我有一组使用ng-repeat重复的元素,每个元素都有一个使用ng-show / ng-hide切换的编辑视图;每个元素的状态保存在本地范围的变量中。我希望能够在特定元素上触发ng-show,但我希望从外部 ng-repeat调用触发器,因此我需要能够访问本地范围变量

任何人都可以指出我正确的方向(或告诉我,如果我正在吠叫错误的树)?

由于

更新:以下链接非常有用,谢天谢地。最后,我为每个重复元素创建了一个指令,并使用指令的link函数将其作用域添加到根作用域的集合中。

3 个答案:

答案 0 :(得分:16)

这是一种非常简单的方法来做我认为你想做的事情(当我需要做类似的事情时我想出了这一点):

我们知道每个重复的项目都有自己的范围。如果我们可以将此范围传递给父范围中定义的方法,那么我们就能够在操作或添加属性方面做到我们想要的。事实证明,这可以通过将this作为参数传递来完成:

实施例

// collection on controller scope
$scope.myCollection = [
  { name: 'John', age: 25 },
  { name: 'Barry', age: 43 },
  { name: 'Kim', age: 26 },
  { name: 'Susan', age: 51 },
  { name: 'Fritz', age: 19 }
];



// template view
<ul>
  <li ng-repeat="person in myCollection">
    <span ng-class="{ bold : isBold }">{{ person.name }} is aged {{ person.age }} </span>
    <button class="btn btn-default btn-xs" ng-click="toggleBold(this)">toggle bold</button>
  </li>
</ul>

所以当我们按下&#34;切换粗体&#34;按钮,我们调用我们需要在控制器的$ scope上定义的$scope.toggleBold()方法。请注意,我们传递this作为参数,实际上是当前的ng-repeat scope对象。

因此我们可以像这样操纵它

$scope.toggleBold = function(repeatScope) {
  if (repeatScope.isBold) {
    repeatScope.isBold = false;
  } else {
    repeatScope.isBold = true;
  }
};

以下是一个工作示例:http://plnkr.co/edit/Vg9ipoEP6wxG8M1kpiW3?p=preview

答案 1 :(得分:10)

Ben Nadel已将a pretty clean solution提供给&#34;如何分配给ngRepeat&#39; $scope&#34;我刚刚在自己的项目中实现的问题。从本质上讲,您可以在ngController旁边添加ngRepeat指令,并操纵控制器内的ngRepeat $scope

以下是我自己设计的示例,该示例演示了如何在控制器中分配ngRepeat $scope。是的,更好的方法来做这件事。有关更好的示例,请参阅Ben Nadel's post

<div ng-controller="ListCtrl">
  <h1>ngRepeat + ngController</h1>
  <ul>
    <li ng-repeat="item in items" ng-controller="ItemCtrl" ng-show="isVisible">
      {{item.name}}
      <button ng-click="hide()">hide me!</button>
    </li>
  </ul>
</div>

<script type="text/javascript">
  var app = angular.module("myApp", []);

  app.controller("ListCtrl", function($scope) {
    $scope.items = [
      {name: "Item 1"},
      {name: "Item 2"},
      {name: "Item 3"}
    ];
  });

  app.controller("ItemCtrl", function($scope) {
    $scope.isVisible = true;
    $scope.hide = function() {
      $scope.isVisible = false;
    };
  });
</script>

编辑:重新阅读您的问题,看到您需要在父作用域中操作一堆子作用域,我认为您的指令方法是可行的方法。我仍然认为这个答案可能对某些人有用,因为我在寻找这个答案时遇到了你的问题。

答案 2 :(得分:1)

当在范围的层次结构中工作时,我觉得用$ emit和$ broadcast调度事件非常有用。 $ emit将向上调度一个事件,以便您的子范围可以通知特定事件的父范围。 $ broadcast是另一回事。

或者,由于子作用域可以访问父作用域属性,因此可以通过对父作用域中的特定属性使用$ watch来触发更改。

更新:至于访问子范围,这可能会对您有用:Get to get all child scopes in Angularjs given the parent scope