Ng-click在ng-repeat内不起作用

Ng-click在ng-repeat内不起作用。 它在外面工作。 我在这里放了一个小提琴

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

正如文中提到的, ng-repeat确实为循环中的每个项目创build了一个子范围。 子范围通过原型inheritance可以访问父范围的variables和方法。 令人困惑的部分是当你作出一个任务时,它将一个新的variables添加到子作用域而不是更新父作用域的属性。 在ng-click ,当你做一个赋值调用tiggerTitle =e.name ,它实际上将一个名为triggerTitle的新variables添加到子作用域。 AngularJS文档在这里称为JavaScript Prototypal Inheritance的部分对此进行了很好的解释。

那么如何解决这个问题,并正确设置模型variables?

一个快速和肮脏的解决scheme是像这样使用$parent来访问父级作用域。

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

点击查看使用$父解决scheme的小提琴的工作版本。

如果您正在处理嵌套模板或嵌套的ng-repeats,使用$parent可能会导致问题。 更好的解决scheme可能是向控制器的作用域添加一个函数,该作用域返回对控制器作用域的引用。 如前所述,子范围可以调用父function,因此可以引用控制器的范围。

 function MyCtrl($scope) { $scope.getMyCtrlScope = function() { return $scope; } ... <a ng-click="getMyCtrlScope().triggerTitle=e.name;getMyCtrlScope().triggerEvent = ... 

点击查看你的小提琴的工作版本使用更好的方法

因为ng-repeat创build一个新的范围。

这已经被无数次的回答了,因为这个细微差别有点难以理解,尤其是如果你不了解js原型inheritance的一切: https : //github.com/angular/angular.js/wiki/Understanding-Scopes

编辑:看来这个答案是非常有争议的。 要明确 – 这是JS的工作原理。 了解JS如何工作之前,你真的不应该尝试学习Angular。 但是,链接似乎错过了

所以,下面是关于JS如何在这种情况下工作的例子:

 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! 

那么,我们该如何解决呢?

那么,我们可以“强迫”自己去经历inheritance链 – 因此我们可以肯定,我们总是访问正确的对象,无论是访问价值还是修改它。

 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 

而不是这个:

 <li ng-repeat="e in events"> <a ng-click="triggerTitle=e.name; triggerEvent = e.action;">{{e.action}} {{e.name}}</a> </li> 

只要这样做:

 <li ng-repeat="e in events"> <a ng-click="$parent.triggerTitle=e.name; $parent.triggerEvent = e.action;">{{e.action}} {{e.name}}</a> </li> 

ng-repeat创build一个新的作用域,你可以使用$parentng-repeat块内部访问父作用域。

这工作

 <body ng-app="demo" ng-controller="MainCtrl"> <ul> <li ng-repeat="action in actions" ng-click="action.action()">{{action.name}}</li> </ul> <script> angular.module('demo', ['ngRoute']); var demo = angular.module('demo').controller('MainCtrl', function ($scope) { $scope.actions = [ { action: function () { $scope.testabc(); }, name: 'foo' }, { action: function () { $scope.testxyz(); }, name: 'bar' } ]; $scope.testabc = function(){ alert("ABC"); }; $scope.testxyz = function(){ alert("XYZ"); }; }); </script> </body> 

在这里,我们可以使用$ parent,以便我们可以访问ng-repeat之外的代码。

HTML代码

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

Angular Js代码

 var myApp = angular.module('myApp',[]); function MyCtrl($scope) { $scope.triggerTitle = 'Select Event'; $scope.triggerEvent = 'x'; $scope.triggerPeriod = 'Select Period'; $scope.events = [{action:'compare', name:'Makes a policy comparison'}, {action:'purchase', name:'Makes a purchase'},{action:'addToCart', name:'Added a product to the cart'}] 

}

你可以在这里testinghttp://jsfiddle.net/xVZEX/96/

用这个

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

我把ng-click转换成ng:点击它开始工作,我还没有find原因,只是很快贴出来分享。

使用带“as”关键字的控制器。

检查控制器上的angularjs 文档 。

对于上述问题:

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

这将把属性和function附加到控制器的范围。