【问题标题】:AngularJS: Binding boolean value to radio button such that it updates model to false on uncheck eventAngularJS:将布尔值绑定到单选按钮,以便在取消选中事件时将模型更新为 false
【发布时间】: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 加载查看/编辑表单页面时,它会正确显示所有联系人的无线电状态。问题来了,在页面加载后,当用户选择另一个联系人作为默认值时。这实际上将新选择的联系人的默认模型值更改为真,但是原始默认联系人的模型值仍然保持为真,即使其无线电状态更改为取消选中/模糊(因为它们具有相同的“名称”值)。

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

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

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-scope radio radio-group


    【解决方案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 时才选择收音机。我快到了,因为假对真工作正常,但反向不起作用。
      猜你喜欢
      • 2013-06-02
      • 2015-04-27
      • 2023-03-18
      • 1970-01-01
      • 2013-06-29
      • 2021-07-19
      • 1970-01-01
      • 1970-01-01
      • 2017-06-22
      相关资源
      最近更新 更多