Ng-click doesn't work inside ng-repeat

Alexandru R picture Alexandru R · May 24, 2013 · Viewed 44.2k times · Source

Ng-click doesn't work from inside ng-repeat. Outside it works. I've put a fiddle here

<div ng-controller="MyCtrl">
 <a ng-click="triggerTitle='This works!'">test</a>
    <h5>Please select trigger event: [{{triggerEvent}}] {{triggerTitle}}</h5>
       <ul class="dropdown-menu">
         <li ng-repeat="e in events">
             <a ng-click="triggerTitle=e.name; triggerEvent = e.action;">{{e.action}} - {{e.name}}</a>
         </li>
       </ul>
</div>

Answer

James Lawruk picture James Lawruk · Sep 25, 2014

As Ven mentioned, ng-repeat does create a child scope for each item in the loop. The child scopes do have access to the parent scope's variables and methods through prototypal inheritance. The confusing part is when you make an assignment, it adds a new variable to the child scope rather than updating the property on the parent scope. In ng-click, when you make an assignment call tiggerTitle =e.name, it actually adds a new variable called triggerTitle to the child scope. The AngularJS docs explains this well in the section here called JavaScript Prototypal Inheritance.

So how do you get around this and set the model variable properly?

A quick and dirty solution is to access the parent scope using $parent like so.

<a ng:click="$parent.triggerTitle=e.name; $parent.triggerEvent = e.action;">...

Click to see a working version of your Fiddle using the $parent solution.

The use of $parent can cause issues if you are dealing with nested templates or nested ng-repeats. A better solution may be to add a function to the controller's scope which returns a reference to the controller's scope. As already mentioned, the child scopes have access to call the parent functions, and thus can reference the controller's scope.

function MyCtrl($scope) {
    $scope.getMyCtrlScope = function() {
         return $scope;   
    }
 ...

<a ng-click="getMyCtrlScope().triggerTitle=e.name;getMyCtrlScope().triggerEvent = ...

Click to see a working version of your Fiddle using the better method