如何将选定的复选框和组名称作为数组中的对象提交

时间:2016-11-27 19:36:02

标签: angularjs

我需要在表单提交时将选定的复选框对象数据单独传递给数组。

服务返回json数据:

[
  {
    "groupName" : "A",
    "groups": [
        "Painting",
        "coloring"
      ]
  },
  {
    "groupName" : "B",
    "groups": [
        "drawing",
        "writing"
      ]
  }
]
当用户选中几个复选框并提交表单时,

服务预期格式:

{
 "groups": [ 
  {
    "category": "A",
    "subCategory": "coloring"
  },
  {
    "category": "B",
    "subCategory": "writing"    
  }
 ]
}

我的控制器:

<div ng-controller="groupCtrl">
<form class="form" name="form" role="form" ng-submit="groupData()" autocomplete="off" novalidate>
        <div ng-repeat="groups in groupsList">
            <p class="category">{{groups.groupName}}</p>
            <p ng-repeat="group in groups.groups" >
                <input type="checkbox" id="group" name="{{group}}" class="group" value="{{group}}" ng-model="groups"> {{group}}
            </p>
        </div>
        <button type="submit" class="button">Save</button>
</form>

控制器:

angular.module('myApp')
.controller("groupCtrl", function($rootScope, $scope, $state, $http) {
    $http.get('group.json').success(function(groupsList) {
        $scope.groupsList = groupsList;
    });

    $scope.groups = {

    }
    $scope.groupData = function () {
        $http.post('<service endpoint>', $scope.groups, {

        })
        .success(function(){
            console.log("success");
        })
        .error(function(){
            console.log("failed.");
        });
    }

});

我是棱角分明的新人。寻求有关如何在控制器中构造数组对象以及在用户选择/取消选择复选框上更新数组对象的帮助。

1 个答案:

答案 0 :(得分:0)

首先,我将api逻辑放入这样的服务中:

angular.module('myApp', [])
//service to handle api communication
.service('apiService', ['$http', function($http) {
   return {
     getGroups: function() {
       return $http.get('http://superapi.com');
     }
   }
 }])

然后你需要从控制器调用api服务并构建你的视图模型:

api.getGroups().then(function(res) {
    //JSON.parse will not be needed if your API returns a JSON body with application/json set as content-type
    $scope.groupsList = JSON.parse(res.data.data);
    //Build up the view model.
    $scope.groupsList.forEach(function(g) {
      $scope.selectedGroups.groups.push({
        category: g.groupName,
        subCategory: []
      });
    });
  },
  function(error) {
            //handle API errors gracefully here.
  });

然后,您可以在表单组件上使用ng-model,用数据

填充它
  <form class="form" name="form" role="form" ng-submit="groupData()" autocomplete="off" novalidate>
    <div ng-repeat="groups in groupsList track by $index">
      <p class="category">{{groups.groupName}}</p>
      <p ng-repeat="group in groups.groups track by $index">
        <input ng-model="selectedGroups.groups[$parent.$index].subCategory" type="checkbox" id="group" name="{{group}}" class="group" ng-true-value="'{{group}}'" ng-init="checked=''" ng-false-value="''"> {{group}}
      </p>
    </div>
    <button type="submit" class="button">Save</button>
  </form>

由于您的api响应模型具有双嵌套层次结构,因此我们需要两个嵌套的ng-repeat循环。然后我们可以利用ng-repeat创建子范围的事实,并且可以使用$ parent访问父范围。这样我们就可以使用该信息通过ng-model绑定到视图模型的正确部分。

ng-model="selectedGroups.groups[$parent.$index].subCategory"

$ parent。$ index是groupsList中的第一个ng-repeat群组

如果您希望能够选择多个子类别,则可以将nd-model绑定到数组中的每个子类别索引,如下所示:

ng-model="selectedGroups.groups[$parent.$index].subCategory[$index]"

这将使用subCategory的索引绑定到数组中的特定位置。

这是一个工作示例:

https://jsfiddle.net/zzq16t8u/4/

这是一个有效的JSFiddle: https://jsfiddle.net/zzq16t8u/3/

现在,当您想要映射到系统指定的请求模型时,您需要在表单submit处理的函数中处理此问题。你可以用ng-true-value做一些聪明的事情,但是你仍然需要在你的数据上做一个JSON.parse,因为它只能在字符串上工作。而且我认为,一旦准备提出请求,我就更好地处理映射到请求模型。

$scope.groupData = function() {
  // map data to the request model specified
  var requestModel = {
    groups: []
  };
  $scope.selectedGroups.forEach(function(group) {
    group.subCategory.forEach(function(subCat) {
      requestModel.groups.push({
        category: group.category,
        subCategory: subCat
      });
    });
  });

这是一个有效的JSFiddle,注意我在这里简化了视图模型,因为我们不再直接绑定到请求模型。

https://jsfiddle.net/zzq16t8u/15/

请注意,这里只需要JSON.parse,因为我无法弄清楚如何让JSFiddle echo服务将json作为真正的json而不是字符串返回,并且示例中的api服务使用了这个echo服务模拟一个真正的http响应,因此需要用真正的http调用替换 - 正如我在这个答案中所示。

希望它有所帮助。