【问题标题】:Radio button not working within nested ng-repeats单选按钮在嵌套的 ng-repeats 中不起作用
【发布时间】:2015-08-10 21:12:45
【问题描述】:

我在嵌套的 ng-repeats 中有一个带有复选框和单选按钮的网页。当我单击复选框时,底层视图模型正在正确更新,但是当我单击单选按钮时,视图模型没有正确更新。在一个组中,当我选择一个选项时,所选模型属性会更新为 true,但另一个不会更改为 false。

例如当我一个一个点击鸡的单选按钮时,它们都变成了真的。当我选择任何一个时,我希望其他的成为 false

我的视图模型如下所示。

$scope.itemGroups = [{
        "name": 'Non Veg',
            "items": [{
            "selected": false,
                "name": 'Chicken',
                "Portions": [{
                "selected": false,
                    "name": '1 Cup'
            }, {
                "selected": false,
                    "name": '2 Cups'
            }, {
                "selected": false,
                    "name": '3 cups'
            }]
        }, {
            "selected": true,
                "name": 'Egg',
                "Portions": [{
                "selected": false,
                    "name": '1 Cup'
            }, {
                "selected": false,
                    "name": '2 Cups'
            }, {
                "selected": false,
                    "name": '3 cups'
            }]
        }]
    }, {
        "name": 'Veggie',
            "items": [{
            "selected": false,
                "name": 'Potato',
                "Portions": [{
                "selected": false,
                    "name": '1 Cup'
            }, {
                "selected": false,
                    "name": '2 Cups'
            }, {
                "selected": false,
                    "name": '3 cups'
            }]
        }, {
            "selected": false,
                "name": 'Tomato',
                "Portions": [{
                "selected": false,
                    "name": '1 Cup'
            }, {
                "selected": false,
                    "name": '2 Cups'
            }, {
                "selected": false,
                    "name": '3 cups'
            }]
        }]
    }];

我绑定到html的方式:

<div ng-repeat="itemGrp in itemGroups">
             <h1>{{itemGrp.name}}</h1>

            <div ng-repeat="item in itemGrp.items">
                <input type="checkbox" ng-model="item.selected" />{{item.name}}
                <label ng-repeat="portion in item.Portions">{{portion.name}}
                    <input type="radio" name="radio_{{itemGrp.name}}" ng-model="portion.selected" ng-value="true" />
                </label>
            </div>
        </div>

小提琴:http://jsfiddle.net/awqv0rb0/16/

您能指导我解决这里的问题吗?有没有更好的方法来实现我在这里尝试做的事情?我需要遍历 JSON 并获取所选项目的值。

【问题讨论】:

    标签: javascript angularjs radio-button angularjs-ng-repeat


    【解决方案1】:

    这是一个小问题。我也是,在更早的阶段就遇到过。

    如果您正在循环一组项目并且每个项目都有一组单选按钮,那么给定项目的所有单选按钮都必须具有“名称”属性值作为项目名称。

    例如。如果项目名称为“鸡”,则所有标记为“1 杯”、“2 杯”、“3 杯”的单选按钮都应具有名称=“{{item.name}}”,即“鸡”。

    代码中的更改点:

    <input type="radio" name="{{item.name}}" ng-model="portion.selected" ng-value="true" />
    

    这是JSFiddle 演示

    【讨论】:

    • 实际上,问题是当你点击 1 Cup 时,它变成了真的。然后,当您单击 2 个杯子时,它变为真,但 1 个杯子也仍然为真。您可以在上面的 JSON 中检查它。
    【解决方案2】:

    您在此处发布的代码与您提供的小提琴不完全匹配,但您的问题是为每个单选按钮提供了自己的名称,因此,它是自己的组。这允许所有单选按钮本质上用作复选框,并且全部设置为 true,而不是只允许一个所需的行为。

    相反,您应该为该项目下的所有单选按钮指定相同的组名,例如:

    name="{{item.name}}" 
    

    完成后,嵌套的 ng-repeats 应该如下所示:

    <div ng-repeat="item in itemGrp.items">
      <input type="checkbox" ng-model="item.selected" />{{item.name}}
      <label ng-repeat="portion in item.Portions">{{portion.name}}
        <input type="radio" name="{{item.name}}" ng-model="portion.selected" ng-value="true" />
      </label>
    </div>
    

    根据您的评论更新

    要在更改每个部分时更新每个部分的selected:true 值,您需要更多代码。这有点乱,所以它可能不是最好的解决方案——但我能够让它工作。

    除了ng-value="true",您还应该在单选按钮中添加ng-change="toggleRadio(itemGrp,item,portion)"。在你的js中,你应该添加以下函数:

     $scope.toggleRadio = function(itemGrp, item, obj) {
          var indexOfItemGrp = $scope.itemGroups.indexOf(itemGrp);
          var indexOfItem = $scope.itemGroups[indexOfItemGrp].items.indexOf(item);
          var indexOfPortion = $scope.itemGroups[indexOfItemGrp].items[indexOfItem].Portions.indexOf(obj);
            angular.forEach($scope.itemGroups[indexOfItemGrp].items[indexOfItem].Portions, function(value,key)     {
                if(indexOfPortion != key) {
                    value.selected = false;
                }
            });
        };
    

    基本上,此代码将遍历 itemGroup 中项目内的所有部分选项,并将其值更新为 false,除非它们是选定的选项。

    您可以在我创建的原始小提琴的分支中看到一个工作示例:here


    更多更新

    看看这个问题:AngularJS Binding Radio Buttons To Booleans Across Multiple Objects。如果您可以更改 json 对象的模型,这可能是一个可行的解决方案。如果您无法更改模型,则手动更新其他值是您最干净的选择。

    【讨论】:

    • 谢谢。我已经纠正了这一点。然而,我面临的主要问题是,当我一个一个地单击鸡的单选按钮时,它们在视图模型中都变为真。当我选择一个时,我希望其他的变成假的。请检查上面 JSON 中的值。
    • 太棒了。我现在就这样做。想知道是否有一个更简单的解决方案,只需双向绑定!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-25
    • 2015-05-07
    • 2015-09-27
    相关资源
    最近更新 更多