将复选框的ID绑定到数组

时间:2016-05-30 06:36:57

标签: javascript angularjs

我有一个包含对象的视图模型,用于显示一些复选框:

components =  {
  "ComponentInfos": [
    {
      "Id": "1abb0ee5-7e44-4e45-92da-150079066e99",
      "FriendlyName": "Component1",
      "LimitInfos": [
        {
          "Id": "4b7cd37a-2378-4f4f-921b-e0375d60d19c",
          "FriendlyName": "Component1 Full",
        },
        {
          "Id": "ff9ebe78-fbe4-4a26-a3df-6ec8e52cd0f2",
          "FriendlyName": "Component1 Light",
        }
      ]
    }

我可以使用FriendlyName作为标签创建复选框:     

<h4>{{l.FriendlyName}}</h4>

<div>
    <div ng-repeat="limitinfo in l.LimitInfos">
        <label>
            <input type="checkbox" ng-model="vm.settings.ComponentInfos[limitinfo.Id]" 
            value="{{limitinfo.Id}}"/> {{limitinfo.FriendlyName}}
        </label>
    </div>
</div>

我想将所选的LimitInfo.Id存储在array的每个所选复选框中。我能够将它们存储在这样的对象中:

settings = {
    "ComponentInfos" : {}
  }; 

结果示例:

"2e80bedb-4a18-4cc4-bdfd-837ffa130947": true,
"add1edf8-4f11-4178-9c78-d591a6f590e3": true

我需要的是将LimitInfo.Id存储在这样的array中:

settings = {
    "ComponentInfos" : []
  };

预期结果:

"2e80bedb-4a18-4cc4-bdfd-837ffa130947", "add1edf8-4f11-4178-9c78-d591a6f590e3"

我将代码上传到Plunker

5 个答案:

答案 0 :(得分:2)

一线解决方案

您可以在vanilla JS(ES5及更高版本,现代浏览器)中执行以下操作

var data = {
    "a": true,
    "b": false,
    "c": true,
    "d": false,
    "e": true,
    "f": true
  }

var arr = Object.keys(data).filter( key => !!data[key] );

// ['a', 'c', 'e', 'f']

答案 1 :(得分:2)

您可以使用自定义控制器方法在复选框上使用ng-click方法来推送到该阵列。

<input type="checkbox" ng-model="vm.settings.ComponentInfos[limitinfo.Id]" 
                value="{{limitinfo.Id}}" ng-click="toggleSelection(limitinfo.ImpliedLimits)"/> 



$scope.toggleSelection = function toggleSelection(item) {
    var idx = $scope.vm.settings.ComponentInfos.indexOf(item);
    if (idx > -1) {
      $scope.vm.settings.ComponentInfos.splice(idx, 1);
    }
    else {
      $scope.vm.settings.ComponentInfos.push(item[0]);
    }
};

请参阅此plnkr

请参阅此answer

答案 2 :(得分:1)

我是angularJS的新手,试试这个:

将此代码段添加到app.js

this.data =[];
this.selection = function(){
    this.data =[];
    angular.forEach(this.settings["ComponentInfos"], function(value, key) {
      if(value)
        this.push(key);
    }, this.data);
 }

这是index.html的主体

<div ng-repeat="l in vm.components.ComponentInfos">

<h4>{{l.FriendlyName}}</h4>

<div>
    <div ng-repeat="limitinfo in l.LimitInfos">
        <label>
            <input type="checkbox" ng-model="vm.settings.ComponentInfos[limitinfo.Id]" ng-click="vm.selection()"
            value="{{limitinfo.Id}}"/> {{limitinfo.FriendlyName}}
        </label>
    </div>
</div>
</div>
<hr>
<pre>
 {{vm.settings | json }}
 {{vm.data}}
</pre>

答案 3 :(得分:1)

您可以使用ng-click并更新您的列表。 我已将此添加到您的MyViewModel函数中,并将ComponentInfos的类型更改为数组。

this.update = function (value) {
    var exists = false;
    for (var elem of this.settings["ComponentInfos"]){
      if (elem === value) {
        exists = true;
      }
    }

    if(exists) {
      var index = this.settings["ComponentInfos"].indexOf(value);
      this.settings["ComponentInfos"].splice(index,1);
    } else {
      this.settings["ComponentInfos"].push(value);
    }
  }

此外,您需要将html中的输入更改为

<input type="checkbox" ng-click="vm.update(limitinfo.Id)"/> {{limitinfo.FriendlyName}}

答案 4 :(得分:1)

{p> Demo directive

var app = angular.module('plunker', []);

app.directive('myCheckbox',function(){
  return {
    restrict:'EA',
    template:'<label>'
                +'<input type="checkbox" ng-model="model" ng-change="toggleModel()" /> {{label}}'
            +'</label>',
    replace: true,
    scope:{
      label:'@',
      value:'@',
      output:'='
    },
    link:function(scope,elements,attrs){

      //init checked status
      scope.model=scope.output.indexOf(scope.value) > -1;
      
      //binding click replace watch model
      scope.toggleModel = function(){
        if(scope.model){
          scope.output.push(scope.value);
          return false;
        }
        scope.output.splice(scope.output.indexOf(scope.value),1);
      }
      
    }
  }
  
});

function MyViewModel()
{
  this.components =  {
  "ComponentInfos": [
    {
      "Id": "1abb0ee5-7e44-4e45-92da-150079066e99",
      "FriendlyName": "Component1",
      "LimitInfos": [
        {
          "Id": "4b7cd37a-2378-4f4f-921b-e0375d60d19c",
          "FriendlyName": "Component1 Full",
          "ImpliedLimits": [
            "ff9ebe78-fbe4-4a26-a3df-6ec8e52cd0f2"
          ]
        },
        {
          "Id": "ff9ebe78-fbe4-4a26-a3df-6ec8e52cd0f2",
          "FriendlyName": "Component1 Light",
          "ImpliedLimits": [
            "4f74abce-5da5-4740-bf89-dc47dafe6c5f"
          ]
        },
        {
          "Id": "4f74abce-5da5-4740-bf89-dc47dafe6c5f",
          "FriendlyName": "Component2 User",
          "ImpliedLimits": []
        }
      ]
    },
    {
      "Id": "ad95e191-26ee-447a-866a-920695bb3ab6",
      "FriendlyName": "Component2",
      "LimitInfos": [
        {
          "Id": "8d13765a-978e-4d12-a1aa-24a1dda2149b",
          "FriendlyName": "Component2 Full",
          "ImpliedLimits": [
            "4f74abce-5da5-4740-bf89-dc47dafe6c5f"
          ]
        },
        {
          "Id": "2e80bedb-4a18-4cc4-bdfd-837ffa130947",
          "FriendlyName": "Component2 Light",
          "ImpliedLimits": [
            "4f74abce-5da5-4740-bf89-dc47dafe6c5f"
          ]
        },
        {
          "Id": "add1edf8-4f11-4178-9c78-d591a6f590e3",
          "FriendlyName": "Component2 Viewer",
          "ImpliedLimits": [
            "4f74abce-5da5-4740-bf89-dc47dafe6c5f"
          ]
        }
      ]
    }
  ]
};

  this.settings = {
    "ComponentInfos" : ["4b7cd37a-2378-4f4f-921b-e0375d60d19c","2e80bedb-4a18-4cc4-bdfd-837ffa130947"]
  };
}



app.controller('MainCtrl', function($scope) {
  $scope.vm = new MyViewModel();
});
<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.20/angular.js" data-semver="1.3.20"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <div ng-repeat="l in vm.components.ComponentInfos">

    <h4>{{l.FriendlyName}}</h4>

    <div>
        <div ng-repeat="limitinfo in l.LimitInfos">
            <my-checkbox label="{{limitinfo.FriendlyName}}" value="{{limitinfo.Id}}" output="vm.settings.ComponentInfos"></my-checkbox>
        </div>
    </div>
  </div>
  
  
  <hr>
  <pre>
    {{vm.settings | json }}
  </pre>
  
  </body>

</html>