Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: Setting a variable in a ng-repeat generated scope

How do I access the set of scopes generated by an ng-repeat?

I suppose at the heart of this is the fact that I don't understand quite how the relationship works between a) the collection of objects that I pass into the ng-repeat directive and b) the collection of scopes that it generates. I can play around with (a), which the ng-repeat scope watches and picks up, but how do I set variables on the scope itself (b)?

My use case is that I have a set of elements repeating using ng-repeat, each of which has an edit view that gets toggled using ng-show/ng-hide; the state for each element is held in a variable in the local scope. I want to be able to trigger an ng-show on a particular element, but I want the trigger to be called from outside the ng-repeat, so I need to be able to access the local scope variable.

Can anyone point me in the right direction (or tell me if I'm barking up the wrong tree)?

Thanks

Update: Link below was very helpful thankful. In the end I created a directive for each of the repeating elements, and used the directive's link function to add its scope to a collection on the root scope.

like image 828
Steve Avatar asked Jul 24 '13 08:07

Steve


People also ask

Does ng-repeat create a new scope?

Each iteration of ng-repeat creates a new child scope, and that new child scope always gets a new property.

How do I get an index value in ng-repeat?

Note: The $index variable is used to get the Index of the Row created by ng-repeat directive. Each row of the HTML Table consists of a Button which has been assigned ng-click directive. The $index variable is passed as parameter to the GetRowIndex function.

What can I use instead of NG-repeat?

You can consider using transclusion inside a custom directive, to achieve the behavior you are looking for without using ng-repeat.

What does this directive do in AngularJS does ng-repeat?

AngularJS ng-repeat Directive The ng-repeat directive repeats a set of HTML, a given number of times. The set of HTML will be repeated once per item in a collection. The collection must be an array or an object.


1 Answers

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

like image 108
Michael Bromley Avatar answered Oct 11 '22 21:10

Michael Bromley