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>