内有角度单选按钮模型ng重复

Angular radio button model inside ng-repeat

本文关键字:模型 ng 重复 单选按钮      更新时间:2023-09-26

我觉得我只是错过了什么,但我看不清是什么。我似乎无法使单选按钮的值与复选框的行为方式相同。我做错了什么?

下面是一个演示:http://jsfiddle.net/vwJ6a/2/

以下是我的HTML看起来像的想法

<tr ng-repeat="contact in ContactsList">
    <td>{{contact.name}}</td>
    <td>{{contact.email}}</td>
    <td ng-class="{'success':contact.isPrimary}">
        <input type="radio" name="radio-primary" ng-model="contact.isPrimary" />
    </td>
    <td ng-class="{'success':contact.isTechnical}">
        <input type="checkbox" ng-model="contact.isTechnical" />
    </td>
</tr>

这是我的控制器

function MyCtrl($scope) {
    $scope.ContactsList = [{
        name: "John Doe",
        email: "joDoe@domain.com",
        isPrimary: false,
        isTechnical: true
    }, {
        name: "Jane Doe",
        email: "jaDoe@domain.com",
        isPrimary: true,
        isTechnical: false
    }, {
        name: "Bill Murray",
        email: "bMurray@domain.com",
        isPrimary: false,
        isTechnical: false
    }, {
        name: "Someone Dude",
        email: "someone@domain.com",
        isPrimary: false,
        isTechnical: false
    }];
}

好问题!我遇到了一个类似的问题,并实施了一种变通办法。首先,我不认为你希望单选按钮的行为与复选框相同。复选框允许多个值,而无线电不允许。也许这很清楚,我只是想说明一下,以防止误解。

AngularJS文档对单选按钮的使用进行了一些解释。https://docs.angularjs.org/api/ng/input/input[收音机]这个解释没有考虑到真正的"动态"环境。正如您所看到的,在示例中,颜色是以前缀为前缀的。我假设,您希望您的表是完全动态的,没有任何前缀。

我做的第一件事是对HTML进行以下更改:

<form name="myForm" ng-controller="MyCtrl">
    <h4>Primary: {{GetPrimaryContact().email}}</h4>
    <table class="table table-bordered table-striped">
        <thead>
        <tr>
            <th>Name</th>
            <th>Email</th>
            <th>Primary</th>
            <th>Technical</th>
            <th>Sales</th>
            <th>Billing</th>
            <th>Emergency</th>
        </tr>
        </thead>
        <tbody>
        <tr ng-repeat="contact in ContactsList">
            <td>{{contact.name}}</td>
            <td>{{contact.email}}</td>
            <td ng-class="{'success':contact.isPrimary == 'true'}">
                <input type="radio" name="radio-primary" ng-model="contact.isPrimary" value="true" ng-change="update($index)" />
            </td>
            <td ng-class="{'success':contact.isTechnical}">
                <input type="checkbox" ng-model="contact.isTechnical" />
            </td>
            <td ng-class="{'success':contact.isSales}">
                <input type="checkbox" ng-model="contact.isSales" />
            </td>
            <td ng-class="{'success':contact.isBilling}">
                <input type="checkbox" ng-model="contact.isBilling" />
            </td>
            <td ng-class="{'success':contact.isEmergency}">
                <input type="checkbox" ng-model="contact.isEmergency" />
            </td>
        </tr>
        </tbody>
    </table>
</form>

success类检查将isPrimary与字符串"true"进行比较。在比较单选按钮时,我不能使用真正的布尔值。

此外,现在还有一个value="true",它是比较所必需的(它检查行,其中isPrimary实际上是true(。最后是ng-change部分的一个新方法。我们需要这个,因为当一个值变为true时,我们需要告诉控制器其他值都是false。这就是为什么我们还将ng-repeat迭代的$index赋予该方法,因为当前更改为true的值不需要再次为false

这是新的控制器:

function MyCtrl($scope) {
    $scope.ContactsList = [{
        name: "John Doe",
        email: "joDoe@domain.com",
        isPrimary: 'false',
        isTechnical: true,
        isSales: false,
        isBilling: true,
        isEmergency: true
    }, {
        name: "Jane Doe",
        email: "jaDoe@domain.com",
        isPrimary: 'true',
        isTechnical: false,
        isSales: false,
        isBilling: true,
        isEmergency: true
    }, {
        name: "Bill Murray",
        email: "bMurray@domain.com",
        isPrimary: 'false',
        isTechnical: false,
        isSales: true,
        isBilling: false,
        isEmergency: false
    }, {
        name: "Someone Dude",
        email: "someone@domain.com",
        isPrimary: 'false',
        isTechnical: false,
        isSales: false,
        isBilling: false,
        isEmergency: true
    }];
    $scope.GetPrimaryContact = function () {
        return _.findWhere($scope.ContactsList, {
            isPrimary: 'true'
        });
    };
    $scope.update = function(index) {
        for (var i=0;i<$scope.ContactsList.length;i++) {
            if (index != i) {
                $scope.ContactsList[i].isPrimary = 'false';
            }
        }
    };
}

控制器包括isPrimary使用Strings而不是Boolean的更改以及新的update()方法。以下是jsfiddle中一个工作演示的链接:http://jsfiddle.net/vwJ6a/20/

更新:

Chris和我显然找到了一种方法,在ng repeat中为单选按钮使用真正的布尔值。为了使用它,必须使用ng-value="true"而不是value="true"value似乎不起作用,我在这里得到了这个想法:AngularJS-将单选按钮绑定到具有布尔值的模型

HTML部分将如下所示:

<form name="myForm" ng-controller="MyCtrl">
    <h4>Primary: {{GetPrimaryContact().email}}</h4>
    <table class="table table-bordered table-striped">
        <thead>
        <tr>
            <th>Name</th>
            <th>Email</th>
            <th>Primary</th>
            <th>Technical</th>
            <th>Sales</th>
            <th>Billing</th>
            <th>Emergency</th>
        </tr>
        </thead>
        <tbody>
        <tr ng-repeat="contact in ContactsList">
            <td>{{contact.name}}</td>
            <td>{{contact.email}}</td>
            <td ng-class="{'success':contact.isPrimary}">
                <input type="radio" name="radio-primary" ng-value="true" ng-model="contact.isPrimary" ng-checked="contact.isPrimary" ng-change="UpdatePrimary(contact)" />
            </td>
            <td ng-class="{'success':contact.isTechnical}">
                <input type="checkbox" ng-model="contact.isTechnical" />
            </td>
            <td ng-class="{'success':contact.isSales}">
                <input type="checkbox" ng-model="contact.isSales" />
            </td>
            <td ng-class="{'success':contact.isBilling}">
                <input type="checkbox" ng-model="contact.isBilling" />
            </td>
            <td ng-class="{'success':contact.isEmergency}">
                <input type="checkbox" ng-model="contact.isEmergency" />
            </td>
        </tr>
        </tbody>
    </table>
</form>

控制器是这样的:

function MyCtrl($scope) {
    $scope.ContactsList = [{
        name: "John Doe",
        email: "joDoe@domain.com",
        isPrimary: false,
        isTechnical: true,
        isSales: false,
        isBilling: true,
        isEmergency: true
    }, {
        name: "Jane Doe",
        email: "jaDoe@domain.com",
        isPrimary: true,
        isTechnical: false,
        isSales: false,
        isBilling: true,
        isEmergency: true
    }, {
        name: "Bill Murray",
        email: "bMurray@domain.com",
        isPrimary: false,
        isTechnical: false,
        isSales: true,
        isBilling: false,
        isEmergency: false
    }, {
        name: "Someone Dude",
        email: "someone@domain.com",
        isPrimary: false,
        isTechnical: false,
        isSales: false,
        isBilling: false,
        isEmergency: true
    }];
    $scope.GetPrimaryContact = function () {
        return _.findWhere($scope.ContactsList, {
            isPrimary: true
        });
    };
    $scope.UpdatePrimary = function(contact) {
        _.each($scope.ContactsList, function(x) {
            x.isPrimary = (x.email === contact.email);
        });
    };
}

以下是jsfiddle中的演示:http://jsfiddle.net/vwJ6a/24/

主要区别在于复选框允许多次选择,而单选按钮不允许。这就是为什么单选按钮应该共享相同的型号。在您的情况下,ngModel指向不同的对象。

这就是我绕过它的方法:

<td ng-class="{'success':primaryContact.email == contact.email}">
    <input type="radio" name="radio-primary" ng-model="primaryContact.email" 
    ng-value="contact.email"/>
</td>

JS

$scope.primaryContact = {
    email:"jaDoe@domain.com"
};

更新的Fiddle

我相信,如果您在无线电输入行中添加value="1",您就会得到您想要的结果。

<input type="radio" value="1" name="radio-primary" ng-model="contact.isPrimary" />