Ng-click在ng-repeat内部不起作用。外面有效。 我放了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>
答案 0 :(得分:52)
正如Ven所说,ng-repeat
确实为循环中的每个项创建子范围。子范围通过原型继承可以访问父范围的变量和方法。令人困惑的部分是,当您进行赋值时,它会向子范围添加一个新变量,而不是更新父范围上的属性。在ng-click
中,当您进行作业调用tiggerTitle =e.name
时,它实际上会向子作用域添加一个名为triggerTitle
的新变量。 AngularJS文档在此处称为JavaScript Prototypal Inheritance的部分中对此进行了解释。
那么你如何解决这个问题并正确设置模型变量呢?
快速而肮脏的解决方案是使用$parent
来访问父作用域。
<a ng:click="$parent.triggerTitle=e.name; $parent.triggerEvent = e.action;">...
Click to see a working version of your Fiddle using the $parent solution.
如果您正在处理嵌套模板或嵌套的ng-repeats,则$parent
的使用可能会导致问题。更好的解决方案可能是向控制器的范围添加一个函数,该函数返回对控制器范围的引用。如前所述,子作用域可以调用父函数,因此可以引用控制器的作用域。
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
答案 1 :(得分:14)
因为ng-repeat
会创建一个新范围。
这已经被回答了很多次,因为细微差别有点难以理解,特别是如果你不了解js的原型继承的所有内容: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!
那么,我们如何解决这个问题呢?
好吧,我们可以“强迫”自己通过继承链 - 因此我们将确保我们始终访问正确的对象,无论是访问价值还是修改它。
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
答案 2 :(得分:6)
而不是:
<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
创建新范围,您可以使用$parent
从ng-repeat
块内访问父范围。
答案 3 :(得分:3)
这里我们可以使用$ 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'}]
}
进行测试答案 4 :(得分:1)
本作品
<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>
答案 5 :(得分:0)
使用此
<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:点击它开始工作,我还没找到原因,只是快速发布分享。
答案 6 :(得分:0)
我长时间在网上浏览,寻找ng-repeat在其中创建自己范围的问题的答案。在ng-repeat中更改变量时,视图不会更新文档中的其他位置。
最后我找到的解决方案就是一个词,没有人告诉你。
这是$ parent。在变量名之前,它将在全局范围内更改其值。
所以
ng-click="entryID=1"
成为ng-click="$parent.entryID=1"
答案 7 :(得分:-1)
使用带有'as'关键字的控制器。
检查控制器上的angularjs上的documentation。
对于上述问题:
<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>
这会将属性和功能附加到控制器的范围。