AngularJS (1.5.0) 嵌套 ng-repeat 与单选按钮未正确初始化检查

问题描述 投票:0回答:1

我使用“动态名称属性”技术。 我正在使用 AngularJS 版本 1.5.0。 当我运行

这个AngularJS示例(下面的代码)

时,它嵌套了ng-repeats(所以我使用$index

$parent.$index
),我希望在渲染时检查正确的单选按钮。
查看下面的截图,第二组单选按钮被选中,第一组没有被选中。

screenshot of the initial rendering of this stackblitz https://stackblitz.com/edit/angularjs-rzsjbr?file=index.html -- the second group of radio buttons are checked properly but the first group of radio buttons are not checked <div id="app"> <div ng-controller="RadioController"> <div ng-repeat="outer_level in outer_levels"> <h1>Outer Level {{ $index }}</h1> <div ng-repeat="inner_level in outer_level.inner_levels"> <h2>Inner Level {{ $index }}</h2> <input type="radio" name="radio_{{$parent.$index}}_{{$index}}" id="radio_{{$parent.$index}}_{{$index}}" value="All" ng-model="inner_level.val" /> <label for="radio_{{$parent.$index}}_{{$index}}"> All</label> <input type="radio" name="radio_{{$parent.$index}}_{{$index}}" id="radio_{{$parent.$index}}_{{$index}}" value="Any" ng-model="inner_level.val" /> <label for="radio_{{$index}}"> Any</label> </div> </div> </div> </div>

Javascript:

window.app = angular .module('app', []) .controller('RadioController', function ($scope) { $scope.message = 'Radio'; $scope.outer_levels = [ { inner_levels: [ { val: 'All', }, { val: 'Any', }, ], }, ]; }); angular.bootstrap(document.getElementById('app'), ['app']);

单选按钮选中属性是在动态名称属性解析之前设置的。
所以所有 4 个单选按钮都使用相同的名称:
radio_{{$parent.$index}}_{{$index}}

选中第二组单选按钮,取消选中第一组单选按钮。 具体来说,在

AngularJS 源代码
中,我在

radioInputType

控制器中的 $render 函数中设置了一个断点:

ctrl.$render = function() {
  var value = attr.value;
  // at this breakpoint, I inspect element[0], and the value of the name attribute is:
  // radio_{{$parent.$index}}_{{$index}}
  element[0].checked = (value == ctrl.$viewValue);
};
所以我有一些解决方法:

不要为 name 属性使用值——它是可选的,因此 AngularJS 会

自动分配一个 name 属性

。 StackBlitz
    here 演示了这是可行的。
  • 显然单选按钮可以有一个值/被“选中”之前 周围添加一个新的
  • inner_level
  • 元素,以便无线电组名称具有范围。 StackBlitz
    here 演示了这将起作用。
    。在
    这个答案
    中建议,但可能会影响您的表单验证。 请注意,原生 HTML <form> 元素
  • 奇怪的是,
  • attr
     对象从第一次附加单选按钮指令时就具有正确的名称,但是 DOM 
    element[0].name
      名称属性直到后来才更新,除非我添加上面的“修复”,否则单选按钮此时按钮不会重新渲染...
    • 
      
      有些事情是行不通的...
  • 我可以使用

ng-init

策略为外部
    $index
  • 创建一个别名(所以我有一个 $parent.$index
     的别名)
    但它不起作用
    在我的示例中,我可以完全删除
    {{$parent.$index}}它可以工作
  • ,(这可以深入了解
  • $render
    函数如何在
    名称属性解析后触发...),但我不认为修复是在具有多个 $parent 级别的场景中就足够了...名称将不明确(即
    outer_levels[0]
    outer_levels[1] 将具有具有相同名称的单选按钮)
    
    
    其他想法:
    也许我可以更新 Angular。当我从
  • 1.5.0更新到1.7.0时,它不起作用
...

    还有其他建议给我吗?
  • 嘿,问题是由于
id

name
angularjs radio-button angularjs-ng-repeat
1个回答
0
投票
ng-id

ng-name
,以便我们不使用插值,然后它开始工作。
之前:
    <input
      type="radio"
      name="radio_{{$parent.$index}}_{{$index}}"
      id="radio_{{$parent.$index}}_{{$index}}"
      value="All"
      ng-model="inner_level.val"
    />
之后:

<input type="radio" ng-name="'radio_' + $parent.$index + $index" ng-id="'radio_' + $parent.$index + $index" value="All" ng-model="inner_level.val" />

window.app = angular
  .module('app', [])
  .controller('RadioController', function($scope) {
    $scope.message = 'Radio';
    $scope.val = 'All'
    $scope.outer_levels = [{
      inner_levels: [{
          val: 'All',
        },

        {
          val: 'Any',
        },

        {
          val: 'Any',
        },
      ],
    }, ];
  });
angular.bootstrap(document.getElementById('app'), ['app']);

<script src="https://code.angularjs.org/1.5.0/angular.min.js"></script> <div id="app"> <div ng-controller="RadioController"> <div ng-repeat="outer_level in outer_levels"> <h1>Outer Level {{ $index }}</h1> <div ng-repeat="inner_level in outer_level.inner_levels"> <h2>Inner Level {{ $index }}</h2> <input type="radio" ng-name="'radio_' + $parent.$index + $index" ng-id="'radio_' + $parent.$index + $index" value="All" ng-model="inner_level.val" /> <label for="radio_{{$parent.$index}}_{{$index}}"> All</label> <input type="radio" ng-name="'radio_' + $parent.$index + $index" ng-id="'radio_' + $parent.$index + $index" value="Any" ng-model="inner_level.val" /> <label for="radio_{{$index}}"> Any</label> </div> </div> </div> </div>


    
	
© www.soinside.com 2019 - 2024. All rights reserved.