17

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

我想这个问题的核心是我不太了解 a) 我传递给 ng-repeat 指令的对象集合和 b) 它生成的范围集合之间的关系是如何工作的。我可以玩(a),ng-repeat 范围监视和拾取,但是我如何在范围本身上设置变量(b)?

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

谁能指出我正确的方向(或者告诉我我是不是找错了树)?

谢谢

更新: 下面的链接非常有帮助,谢谢。最后,我为每个重复元素创建了一个指令,并使用该指令的链接函数将其范围添加到根范围的集合中。

4

3 回答 3

19

Here is a pretty simple way to do what I think you are trying to do (I figured this out when I needed to do something similar):

We know that each repeated item has it's own scope created for it. If we could pass this scope to a method defined on the parent scope, then we'd be able to do what we want with it in terms of manipulating or adding properties. It turn out this can be done by passing this as an argument:

Example

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

So when we press the "toggle bold" button, we are calling the $scope.toggleBold() method that we need to define on the controller's $scope. Notice that we pass this as the argument, which is actually the current ng-repeat scope object.

Therefore we can manipulate it like this

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

Here is a working example: http://plnkr.co/edit/Vg9ipoEP6wxG8M1kpiW3?p=preview

于 2014-04-30T09:30:43.823 回答
11

Ben Nadel为“我如何分配给's ”问题提供了一个非常干净的解决方案,我刚刚在自己的项目中实现了该解决方案。本质上,您可以在 ,旁边添加一个指令,并在控制器内部操作' 。ngRepeat$scopengControllerngRepeatngRepeat$scope

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

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

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

于 2014-05-22T15:50:59.940 回答
1

在范围层次结构中工作时,我发现使用 $emit 和 $broadcast 调度事件非常有用。$emit 向上调度一个事件,以便您的子作用域可以通知父作用域特定事件。$broadcast 则相反。

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

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

于 2013-07-24T10:23:29.780 回答