Angularjs 1.5.8 - 2 级 ng-repeat 内的单选按钮列表无法正常工作
Angularjs 1.5.8 - radio button list inside 2 levels of ng-repeat not working properly
请检查下面的代码,
angular.module('myApp', []).controller('myController', ['$scope',
function($scope) {
setTimeout(function() {
$scope.policies = [{
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}, {
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}];
$scope.$apply();
}, 1000)
}
]);
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
<div ng-app='myApp'>
<div ng-controller='myController'>
<div ng-repeat='policy in policies'>
<div ng-repeat='driver in policy.drivers'>
Gender : M
<input type='radio' name='driverGender{{$index}}{{$parent.$index}}' value='M' ng-model='driver.gender' />F
<input type='radio' ng-model='driver.gender' name='driverGender{{$index}}{{$parent.$index}}' value='F' />
</div>
</div>
</div>
</div>
我试图在 2 级 ng-repeat 中实现一对单选按钮。我可以检查单选按钮,值按预期更改。但是如果值是从控件分配的,则只有最后一对单选按钮得到更新。当我将版本更改为 1.2.0 时,它工作正常。请检查下面的示例
angular.module('myApp', []).controller('myController', ['$scope',
function($scope) {
setTimeout(function() {
$scope.policies = [{
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}, {
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}];
$scope.$apply();
}, 1000)
}
]);
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.0/angular.js"></script>
<div ng-app='myApp'>
<div ng-controller='myController'>
<div ng-repeat='policy in policies'>
<div ng-repeat='driver in policy.drivers'>
Gender : M
<input type='radio' name='driverGender{{$index}}{{$parent.$index}}' value='M' ng-model='driver.gender' />F
<input type='radio' ng-model='driver.gender' name='driverGender{{$index}}{{$parent.$index}}' value='F' />
</div>
</div>
</div>
</div>
代码或其他替代方法有问题吗?
你应该做一个循环并为所有这些分配你想要的值:
angular.forEach($scope.policies, function(policy) {
angular.forEach(policy.drivers, function(driver) {
driver.gender = "M";
});
});
希望对您有所帮助。
我认为唯一的问题是单选按钮名称存在冲突,所以如果您将单选按钮代码替换为以下代码:
<input type='radio' name='driverGender{{$index}}{{$parent.$index}}0' value='M' ng-model='driver.gender' />F
<input type='radio' ng-model='driver.gender' name='driverGender{{$index}}{{$parent.$index}}1' value='F' />
工作演示请参考plnkr:
https://plnkr.co/edit/GKtCRtunNrvLiksbCuXE?p=preview
我个人在这个问题上花了2-3个小时,没有找到这个问题的真正原因。我唯一得到的是这个东西在 Angular 版本 1.3.0-beta.19.
中开始制动
变更日志是 130-beta19-rafter-ascension-2014-08-22。
注意:此答案并未向您提供此问题的实际原因。
要解决此问题,请考虑从您的 input[type=radio]
字段中删除 name
属性,因为收音机与相同的 ng-model
配合使用效果很好,根据文档,name
也是可选的。 https://docs.angularjs.org/api/ng/input/input%5Bradio%5D
angular.module('myApp', []).controller('myController', ['$scope',
function($scope) {
setTimeout(function() {
$scope.policies = [{
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}, {
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}];
$scope.$apply();
}, 1000)
}
]);
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0-beta.19/angular.js"></script>
<div ng-app="myApp" ng-controller="myController">
{{policies | json}}
<br><br>
<div ng-repeat="policy in policies">
<div ng-repeat="driver in policy.drivers">
Gender : M
<input type="radio" value="M" ng-model="driver.gender" /> F
<input type="radio" ng-model="driver.gender" value="F" />
</div>
</div>
</div>
另一个似乎对我有用的解决方案。考虑使用指令:
angular.module('myApp', []).controller('myController', ['$scope',
function($scope) {
setTimeout(function() {
$scope.policies = [{
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}, {
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}];
$scope.$apply();
}, 1000)
}
]);
angular.module('myApp').directive('radio', function() {
return {
restrict: 'E',
replace: true,
template: '<input type="radio" name="{{getFooName()}}" />',
controller: function($scope) {
$scope.getFooName = function() {
return 'driverGender' + $scope.$index + $scope.$parent.$index;
}
}
}
});
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0-beta.19/angular.js"></script>
<div ng-app="myApp" ng-controller="myController">
{{policies | json}}
<br>
<br>
<div ng-repeat="policy in policies">
<div ng-repeat="driver in policy.drivers">
Gender : M
<radio ng-model="driver.gender" value="M"></radio>F
<radio ng-model="driver.gender" value="F"></radio>
</div>
</div>
</div>
最后我找到了解决方案。我创建了 return 相同的函数,而不是 'driverGender{{$index}}{{$parent.$index}}'
。
$scope.getRadioButtonName=function(index,parentIndex){
return 'gender'+index+parentIndex;
}
在下方查看。
// Code goes here
angular.module('myApp', []).controller('myController', ['$scope',
function($scope) {
$scope.policies = [{
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}, {
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}];
$scope.getRadioButtonName=function(index,parentIndex){
return 'gender'+index+parentIndex;
}
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<div ng-app='myApp'>
<div ng-controller='myController'>
<div ng-repeat='policy in policies'>
<div ng-repeat='driver in policy.drivers'>
Gender : M
<input type='radio' ng-model='driver.gender' name='{{getRadioButtonName($index,$parent.$index)}}' value='M' />F
<input type='radio' ng-model='driver.gender' name='{{getRadioButtonName($index,$parent.$index)}}' value='F' />
</div>
</div>
</div>
</div>
请检查下面的代码,
angular.module('myApp', []).controller('myController', ['$scope',
function($scope) {
setTimeout(function() {
$scope.policies = [{
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}, {
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}];
$scope.$apply();
}, 1000)
}
]);
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
<div ng-app='myApp'>
<div ng-controller='myController'>
<div ng-repeat='policy in policies'>
<div ng-repeat='driver in policy.drivers'>
Gender : M
<input type='radio' name='driverGender{{$index}}{{$parent.$index}}' value='M' ng-model='driver.gender' />F
<input type='radio' ng-model='driver.gender' name='driverGender{{$index}}{{$parent.$index}}' value='F' />
</div>
</div>
</div>
</div>
我试图在 2 级 ng-repeat 中实现一对单选按钮。我可以检查单选按钮,值按预期更改。但是如果值是从控件分配的,则只有最后一对单选按钮得到更新。当我将版本更改为 1.2.0 时,它工作正常。请检查下面的示例
angular.module('myApp', []).controller('myController', ['$scope',
function($scope) {
setTimeout(function() {
$scope.policies = [{
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}, {
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}];
$scope.$apply();
}, 1000)
}
]);
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.0/angular.js"></script>
<div ng-app='myApp'>
<div ng-controller='myController'>
<div ng-repeat='policy in policies'>
<div ng-repeat='driver in policy.drivers'>
Gender : M
<input type='radio' name='driverGender{{$index}}{{$parent.$index}}' value='M' ng-model='driver.gender' />F
<input type='radio' ng-model='driver.gender' name='driverGender{{$index}}{{$parent.$index}}' value='F' />
</div>
</div>
</div>
</div>
代码或其他替代方法有问题吗?
你应该做一个循环并为所有这些分配你想要的值:
angular.forEach($scope.policies, function(policy) {
angular.forEach(policy.drivers, function(driver) {
driver.gender = "M";
});
});
希望对您有所帮助。
我认为唯一的问题是单选按钮名称存在冲突,所以如果您将单选按钮代码替换为以下代码:
<input type='radio' name='driverGender{{$index}}{{$parent.$index}}0' value='M' ng-model='driver.gender' />F
<input type='radio' ng-model='driver.gender' name='driverGender{{$index}}{{$parent.$index}}1' value='F' />
工作演示请参考plnkr: https://plnkr.co/edit/GKtCRtunNrvLiksbCuXE?p=preview
我个人在这个问题上花了2-3个小时,没有找到这个问题的真正原因。我唯一得到的是这个东西在 Angular 版本 1.3.0-beta.19.
中开始制动变更日志是 130-beta19-rafter-ascension-2014-08-22。
注意:此答案并未向您提供此问题的实际原因。
要解决此问题,请考虑从您的 input[type=radio]
字段中删除 name
属性,因为收音机与相同的 ng-model
配合使用效果很好,根据文档,name
也是可选的。 https://docs.angularjs.org/api/ng/input/input%5Bradio%5D
angular.module('myApp', []).controller('myController', ['$scope',
function($scope) {
setTimeout(function() {
$scope.policies = [{
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}, {
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}];
$scope.$apply();
}, 1000)
}
]);
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0-beta.19/angular.js"></script>
<div ng-app="myApp" ng-controller="myController">
{{policies | json}}
<br><br>
<div ng-repeat="policy in policies">
<div ng-repeat="driver in policy.drivers">
Gender : M
<input type="radio" value="M" ng-model="driver.gender" /> F
<input type="radio" ng-model="driver.gender" value="F" />
</div>
</div>
</div>
另一个似乎对我有用的解决方案。考虑使用指令:
angular.module('myApp', []).controller('myController', ['$scope',
function($scope) {
setTimeout(function() {
$scope.policies = [{
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}, {
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}];
$scope.$apply();
}, 1000)
}
]);
angular.module('myApp').directive('radio', function() {
return {
restrict: 'E',
replace: true,
template: '<input type="radio" name="{{getFooName()}}" />',
controller: function($scope) {
$scope.getFooName = function() {
return 'driverGender' + $scope.$index + $scope.$parent.$index;
}
}
}
});
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0-beta.19/angular.js"></script>
<div ng-app="myApp" ng-controller="myController">
{{policies | json}}
<br>
<br>
<div ng-repeat="policy in policies">
<div ng-repeat="driver in policy.drivers">
Gender : M
<radio ng-model="driver.gender" value="M"></radio>F
<radio ng-model="driver.gender" value="F"></radio>
</div>
</div>
</div>
最后我找到了解决方案。我创建了 return 相同的函数,而不是 'driverGender{{$index}}{{$parent.$index}}'
。
$scope.getRadioButtonName=function(index,parentIndex){
return 'gender'+index+parentIndex;
}
在下方查看。
// Code goes here
angular.module('myApp', []).controller('myController', ['$scope',
function($scope) {
$scope.policies = [{
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}, {
drivers: [{
gender: 'M'
}, {
gender: 'F'
}]
}];
$scope.getRadioButtonName=function(index,parentIndex){
return 'gender'+index+parentIndex;
}
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<div ng-app='myApp'>
<div ng-controller='myController'>
<div ng-repeat='policy in policies'>
<div ng-repeat='driver in policy.drivers'>
Gender : M
<input type='radio' ng-model='driver.gender' name='{{getRadioButtonName($index,$parent.$index)}}' value='M' />F
<input type='radio' ng-model='driver.gender' name='{{getRadioButtonName($index,$parent.$index)}}' value='F' />
</div>
</div>
</div>
</div>