Angularjs 1.5.8 - 2级ng-repeat内的单选按钮列表无法正常工作

时间:2016-08-12 13:33:24

标签: javascript angularjs angularjs-ng-repeat radiobuttonlist angularjs-1.5

请检查以下代码,

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>

代码或其他替代方案中是否存在问题?

4 个答案:

答案 0 :(得分:1)

我认为唯一的问题是单选按钮名称会发生​​冲突,所以如果您只是用以下代码替换单选按钮代码:

    <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

答案 1 :(得分:1)

在这个问题上亲自花了2-3个小时后,我没有发现这个问题的实际原因。我得到的唯一一件事就是这件事开始在Angular版1.3.0-beta.19制动。

更改日志为130-beta19-rafter-ascension-2014-08-22

注意:此答案并未提供此问题的实际原因。

要解决此问题,请考虑从name字段中删除input[type=radio]属性,因为收音机只能使用相同的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>

答案 2 :(得分:1)

最后我找到了一个解决方案..而不是$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;
    }
  }
]);

请在下方查看。

&#13;
&#13;
<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>
&#13;
<p xmlns:l=\"http://www.w3.org/1999/xlink\">В истории мирового кинематографа с именем Альфреда Хичкока – режиссера, продюсера, сценариста – неразрывно связан жанр триллера и понятие саспенса. Закомплексованный толстяк обладал волшебным даром, позволявшим ему обращать вечно терзавшие его страхи на пользу творчеству: Хичкок мастерски создавал в своих фильмах атмосферу тревожной неопределенности и напряженного ожидания. Странный, склонный к жестоким розыгрышам человек, в молодости испытавший влияние немецкого и русского кино, не боялся экспериментировать и постоянно использовал новаторские, а порой и шокирующие приемы. Ровесник кинематографа, он рос вместе с ним, создавая и развивая новые жанры, от комедийного триллера до фильма ужасов и тончайшего психологического детектива. Ему довелось работать с самыми звездными актерами Голливуда, такими как Ингрид Бергман, Кэри Грант, Джеймс Стюарт, Грейс Келли. Фильмы Хичкока стали классикой мирового кинематографа, он удостоен звезды на голливудской Аллее славы, почетной награды Американского института кино, ордена Британской империи.</p>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

你应该创建一个循环并为所有这些分配你想要的值:

angular.forEach($scope.policies, function(policy) {
   angular.forEach(policy.drivers, function(driver) {
     driver.gender = "M";
   });
});

希望它有所帮助。