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>
You can consider using transclusion inside a custom directive, to achieve the behavior you are looking for without using ng-repeat.
For a single btn, it's ok to use ng-click or onclick in the ng-app . There is no difference between the two functions. For effective team work, you,d better to have an account with each other. In Angular apps, ng-click is recommended.
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.
Directives that Create Scopes In most cases, directives and scopes interact but do not create new instances of scope. However, some directives, such as ng-controller and ng-repeat, create new child scopes and attach the child scope to the corresponding DOM element.
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
Because ng-repeat
creates a new scope.
This has been answered numerous time, because the nuance is a bit difficult to understand, especially if you don't know everything about js's prototypal inheritance : https://github.com/angular/angular.js/wiki/Understanding-Scopes
EDIT: it seems this answer is very controversial. Just to be clear – this is how JS works. You really shouldn't try to learn Angular before understand how JS works. However, the link does seem to miss
So, here's an example on how JS works in this case:
var a = {value: 5}; var b = Object.create(a); // create an object that has `a` as its prototype // we can access `value` through JS' the prototype chain alert(b.value); // prints 5 // however, we can't *change* that value, because assignment is always on the designated object b.value = 10; alert(b.value); // this will print 10... alert(a.value); // ... but this will print 5!
So, how can we work around that?
Well, we can "force" ourselves to go through the inheritance chain – and thus we'll be sure we're always accessing the correct object, whether accessing value or modifying it.
var a = {obj: {value: 5}}; var b = Object.create(a); // create an object that has `a` as its prototype // we can access `value` through JS' the prototype chain: alert(b.obj.value); // prints 5 // and if we need to change it, // we'll just go through the prototype chain again: b.obj.value = 10; // and actually refer to the same object! alert(b.obj.value == a.obj.value); // this will print true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With