AngularJS:将布尔值绑定到单选按钮,以便在取消选中事件时将模型更新为 false

Posted

技术标签:

【中文标题】AngularJS:将布尔值绑定到单选按钮,以便在取消选中事件时将模型更新为 false【英文标题】:AngularJS: Binding boolean value to radio button such that it updates model to false on uncheck event 【发布时间】:2014-01-21 22:24:26 【问题描述】:

在我的 AngularJS 应用程序中,我在网格中显示联系人数据。我的典型联系人 JSON 如下所示...

[
     type: "IM", value: "mavaze123", default: true ,
     type: "IM", value: "mvaze2014", default: false ,
     type: "IM", value: "mavaze923", default: false ,
     type: "IM", value: "mvaze8927", default: false ,
     type: "Email", value: "mavaze123@abc.com", default: true ,
     type: "Email", value: "mvaze2014@xyz.net", default: false  
]

最后一个属性'default'实际上是一个单选按钮,选择它应该会改变上面JSON中相应联系人类型的原始默认值。每种类型的联系人都可以有一个默认值,即我们可以根据联系人类型对单选按钮进行分组。

<div ng-repeat="contact in contacts">
    <div>contact.type</div>
    <div>contact.value</div>
    <div><input type="radio" name="contact.type" ng-model="contact.default" ng-value="true"/></div>
</div>

注意:上面的代码并不完全一样,但大致相同,如 它将出现在自定义网格组件中。

现在,当我使用上述 JSON 加载查看/编辑表单页面时,它会正确显示所有联系人的无线电状态。问题来了,在页面加载后,当用户选择另一个联系人作为默认值时。这实际上将新选择的联系人的默认模型值更改为真,但是原始默认联系人的模型值仍然保持为真,即使其无线电状态更改为取消选中/模糊(因为它们具有相同的“名称”值)。

我想写一个指令,但我无法在无线电模糊/取消选中事件上触发它。

有很多关于将布尔值绑定到单选按钮的帖子,但我无法在我的场景中使用它,因为我想更新单选按钮组中单个单选按钮的模型值。看看没有代表无线电组的单一模型。

【问题讨论】:

【参考方案1】:

我认为您应该更改设计以将contactscontactTypes 分开并将 存储到联系人类型中的默认联系人。

在您当前的设计中,default 存在重复值,这不是使用 radio 的理想方式。

$scope.contacts = [
         type: "IM", value: "mavaze123" ,
         type: "IM", value: "mvaze2014" ,
         type: "IM", value: "mavaze923" ,
         type: "IM", value: "mvaze8927" ,
         type: "Email", value: "mavaze123@abc.com" ,
         type: "Email", value: "mvaze2014@xyz.net"  
   ];

    $scope.contactTypes = 
        "IM":  default:"mavaze123", //the default is contact with value = mavaze123
        "Email":  default:"mavaze123@abc.com"
   ;

你的html

<div ng-repeat="contact in contacts">
            <div>contact.type</div>
            <div>contact.value</div>
            <div><input type="radio" name="contact.type" ng-model="contactTypes[contact.type].default" ng-value="contact.value"/></div>
        </div>

DEMO

我假设联系人的密钥是value,您可以使用Id 作为您的联系人。

【讨论】:

嗨@khanh-to,我倾向于接受这个,因为我已经开始工作了。但是,我正在考虑对从 REST 响应中获得的相同 JSON 进行操作,并且我需要在修改后将其发布到 REST API。您的解决方案虽然有效,但我需要编写后端逻辑以转换为原始 JSON 格式,同时将其发送到 REST。我快到了,因为从假到真完美,尽管从同一联系人类型组中选择其他收音机时反向失败。 @mavaze:反向失败是什么意思? @mavaze:这个设计没有真假,你把默认联系人的key分配给联系人类型。 嗨@khanh-to,我说的是迄今为止我使用JSON 格式实现的解决方案。首先,我只能从每个组中选择一个。其次,如果 default=false 并且如果我选择了该收音机,则模型将更改为 true,但是,第三,如果我从同一组中选择另一个收音机,则先前选择的收音机虽然会更改其状态(取消选中/模糊),但不会将其模型值更改为 false。 @mavaze:我理解您的问题,正如问题中所述。我的意思是,在新设计中,每个联系人都没有默认值(真或假)。我们将默认设置改为联系人类型。每个联系人类型都存储一个默认联系人的 ID。我们不再关心真假,只关心联系人类型中默认的Id【参考方案2】:

我在输入语句中添加了一个属性指令...

<div ng-repeat="contact in contacts">
    <div>contact.type</div>
    <div>contact.value</div>
    <div><input type="radio" name="contact.type" ng-model="contact.default" ng-value="true" boolean-grid-model /></div>
</div>

还有我的自定义指令...

myModule.directive('booleanGridModel') 
    return 
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, elem, attrs, controller) 
           var radioselected = scope.$eval(attrs.ngModel);
           if(radioSelected) 
               var selectedContact = scope.contact;
               _.each(scope.contacts, function(contact) 
                  if(contact.type === selectedContact.type) 
                      _.isEqual(contact, selectedContact) ? contact.default = true : contact.default = false;
                  
               );
           
       
    ;

【讨论】:

【参考方案3】:

为什么你声明 ng-value="true" 请删除它

<div><input type="radio" name="contact.type" ng-model="contact.default" ng-value="contact.default"/></div>

请在您的值更改代码中使用$scope.$apply()

喜欢下面的东西

$scope.$apply(function ChangeType()

/Code
);

并且您需要将name="contact.type" 更改为name="contact.type$index" 因为有些类型是同名的。

【讨论】:

name="contact.type$index" 不允许从每个组中选择一个默认值,例如一个默认 IM、一个默认电子邮件,但它可能允许选择一个默认联系人所有类型。这不是我想要的。此外,当默认值为 true 时,ng-value="contact.default" 不会显示单选按钮的选择。使用此解决方案,即使 default=false,也将始终选择最后一个单选按钮。当我至少设置 ng-value="true" 时,我确保仅在默认模型值为 true 时才选择收音机。我快到了,因为假对真工作正常,但反向不起作用。

以上是关于AngularJS:将布尔值绑定到单选按钮,以便在取消选中事件时将模型更新为 false的主要内容,如果未能解决你的问题,请参考以下文章

单选按钮的 knockout.js 布尔数据绑定问题

Aurelia在检查更改时将值绑定到单选按钮

Winforms 将枚举绑定到单选按钮

Winforms将Enum绑定到单选按钮

angularjs怎么获取到单选框的值

angularjs怎么获取到单选框的值