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一个新的作用域,你可以使用$parent
从ng-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附加到控制器的范围。