我有一些复选框:

<input type='checkbox' value="apple" checked>
<input type='checkbox' value="orange">
<input type='checkbox' value="pear" checked>
<input type='checkbox' value="naartjie">

我想绑定到我的控制器中的一个列表,这样每当一个复选框被更改时,控制器就会维护一个包含所有选中值的列表,例如,['apple', 'pear']。

Ng-model似乎只能将一个复选框的值绑定到控制器中的一个变量。

是否有其他方法可以将这四个复选框绑定到控制器中的列表?


当前回答

下面的解决方案似乎是个不错的选择,

<label ng-repeat="fruit in fruits">
  <input
    type="checkbox"
    ng-model="fruit.checked"
    ng-value="true"
  > {{fruit.fruitName}}
</label>

在控制器模型中,值果实是这样的

$scope.fruits = [
  {
    "name": "apple",
    "checked": true
  },
  {
    "name": "orange"
  },
  {
    "name": "grapes",
    "checked": true
  }
];

其他回答

灵感来自Yoshi上面的帖子。 这是钱。

(function () { angular .module("APP", []) .controller("demoCtrl", ["$scope", function ($scope) { var dc = this dc.list = [ "Selection1", "Selection2", "Selection3" ] dc.multipleSelections = [] dc.individualSelections = [] // Using splice and push methods to make use of // the same "selections" object passed by reference to the // addOrRemove function as using "selections = []" // creates a new object within the scope of the // function which doesn't help in two way binding. dc.addOrRemove = function (selectedItems, item, isMultiple) { var itemIndex = selectedItems.indexOf(item) var isPresent = (itemIndex > -1) if (isMultiple) { if (isPresent) { selectedItems.splice(itemIndex, 1) } else { selectedItems.push(item) } } else { if (isPresent) { selectedItems.splice(0, 1) } else { selectedItems.splice(0, 1, item) } } } }]) })() label { display: block; } <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="style.css" /> </head> <body ng-app="APP" ng-controller="demoCtrl as dc"> <h1>checkbox-select demo</h1> <h4>Multiple Selections</h4> <label ng-repeat="thing in dc.list"> <input type="checkbox" ng-checked="dc.multipleSelections.indexOf(thing) > -1" ng-click="dc.addOrRemove(dc.multipleSelections, thing, true)" > {{thing}} </label> <p> dc.multipleSelections :- {{dc.multipleSelections}} </p> <hr> <h4>Individual Selections</h4> <label ng-repeat="thing in dc.list"> <input type="checkbox" ng-checked="dc.individualSelections.indexOf(thing) > -1" ng-click="dc.addOrRemove(dc.individualSelections, thing, false)" > {{thing}} </label> <p> dc.invidualSelections :- {{dc.individualSelections}} </p> <script data-require="jquery@3.0.0" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script> <script data-require="angular.js@1.5.6" data-semver="1.5.6" src="https://code.angularjs.org/1.5.6/angular.min.js"></script> <script src="script.js"></script> </body> </html>

你可以结合AngularJS和jQuery。例如,您需要定义一个数组$scope。控制器中的Selected = [];

<label ng-repeat="item in items">
    <input type="checkbox" ng-model="selected[$index]" ng-true-value="'{{item}}'">{{item}}
</label>

您可以获得拥有所选项目的数组。使用方法alert(JSON.stringify($scope.selected)),可以检查选中的项。

有两种方法可以解决这个问题。要么使用简单数组,要么使用对象数组。每种解决方案都有其优缺点。下面你将为每种情况找到一个解决方案。


使用简单数组作为输入数据

HTML可以是这样的:

<label ng-repeat="fruitName in fruits">
  <input
    type="checkbox"
    name="selectedFruits[]"
    value="{{fruitName}}"
    ng-checked="selection.indexOf(fruitName) > -1"
    ng-click="toggleSelection(fruitName)"
  > {{fruitName}}
</label>

适当的控制器代码是:

app.controller('SimpleArrayCtrl', ['$scope', function SimpleArrayCtrl($scope) {

  // Fruits
  $scope.fruits = ['apple', 'orange', 'pear', 'naartjie'];

  // Selected fruits
  $scope.selection = ['apple', 'pear'];

  // Toggle selection for a given fruit by name
  $scope.toggleSelection = function toggleSelection(fruitName) {
    var idx = $scope.selection.indexOf(fruitName);

    // Is currently selected
    if (idx > -1) {
      $scope.selection.splice(idx, 1);
    }

    // Is newly selected
    else {
      $scope.selection.push(fruitName);
    }
  };
}]);

优点:简单的数据结构和切换名称容易处理

缺点:添加/删除很麻烦,因为必须管理两个列表(输入和选择)


使用对象数组作为输入数据

HTML可以是这样的:

<label ng-repeat="fruit in fruits">
  <!--
    - Use `value="{{fruit.name}}"` to give the input a real value, in case the form gets submitted
      traditionally

    - Use `ng-checked="fruit.selected"` to have the checkbox checked based on some angular expression
      (no two-way-data-binding)

    - Use `ng-model="fruit.selected"` to utilize two-way-data-binding. Note that `.selected`
      is arbitrary. The property name could be anything and will be created on the object if not present.
  -->
  <input
    type="checkbox"
    name="selectedFruits[]"
    value="{{fruit.name}}"
    ng-model="fruit.selected"
  > {{fruit.name}}
</label>

适当的控制器代码是:

app.controller('ObjectArrayCtrl', ['$scope', 'filterFilter', function ObjectArrayCtrl($scope, filterFilter) {

  // Fruits
  $scope.fruits = [
    { name: 'apple',    selected: true },
    { name: 'orange',   selected: false },
    { name: 'pear',     selected: true },
    { name: 'naartjie', selected: false }
  ];

  // Selected fruits
  $scope.selection = [];

  // Helper method to get selected fruits
  $scope.selectedFruits = function selectedFruits() {
    return filterFilter($scope.fruits, { selected: true });
  };

  // Watch fruits for changes
  $scope.$watch('fruits|filter:{selected:true}', function (nv) {
    $scope.selection = nv.map(function (fruit) {
      return fruit.name;
    });
  }, true);
}]);

优点:添加/删除非常容易

缺点:有些复杂的数据结构和切换名称是麻烦的或需要一个帮助方法


演示:http://jsbin.com/ImAqUC/1/

试试我的宝贝:

**

myApp.filter('inputSelected', function(){
  return function(formData){
    var keyArr = [];
    var word = [];
    Object.keys(formData).forEach(function(key){
    if (formData[key]){
        var keyCap = key.charAt(0).toUpperCase() + key.slice(1);
      for (var char = 0; char<keyCap.length; char++ ) {
        if (keyCap[char] == keyCap[char].toUpperCase()){
          var spacedLetter = ' '+ keyCap[char];
          word.push(spacedLetter);
        }
        else {
          word.push(keyCap[char]);
        }
      }
    }
    keyArr.push(word.join(''))
    word = [];
    })
    return keyArr.toString();
  }
})

**

然后对于任何带有复选框的ng-model,它将返回你选择的所有输入的字符串:

<label for="Heard about ITN">How did you hear about ITN?: *</label><br>
<label class="checkbox-inline"><input ng-model="formData.heardAboutItn.brotherOrSister" type="checkbox" >Brother or Sister</label>
<label class="checkbox-inline"><input ng-model="formData.heardAboutItn.friendOrAcquaintance" type="checkbox" >Friend or Acquaintance</label>


{{formData.heardAboutItn | inputSelected }}

//returns Brother or Sister, Friend or Acquaintance

根据我在这里的另一篇文章,我已经做了一个可重用的指令。

查看GitHub存储库

(function () { angular .module("checkbox-select", []) .directive("checkboxModel", ["$compile", function ($compile) { return { restrict: "A", link: function (scope, ele, attrs) { // Defining updateSelection function on the parent scope if (!scope.$parent.updateSelections) { // Using splice and push methods to make use of // the same "selections" object passed by reference to the // addOrRemove function as using "selections = []" // creates a new object within the scope of the // function which doesn't help in two way binding. scope.$parent.updateSelections = function (selectedItems, item, isMultiple) { var itemIndex = selectedItems.indexOf(item) var isPresent = (itemIndex > -1) if (isMultiple) { if (isPresent) { selectedItems.splice(itemIndex, 1) } else { selectedItems.push(item) } } else { if (isPresent) { selectedItems.splice(0, 1) } else { selectedItems.splice(0, 1, item) } } } } // Adding or removing attributes ele.attr("ng-checked", attrs.checkboxModel + ".indexOf(" + attrs.checkboxValue + ") > -1") var multiple = attrs.multiple ? "true" : "false" ele.attr("ng-click", "updateSelections(" + [attrs.checkboxModel, attrs.checkboxValue, multiple].join(",") + ")") // Removing the checkbox-model attribute, // it will avoid recompiling the element infinitly ele.removeAttr("checkbox-model") ele.removeAttr("checkbox-value") ele.removeAttr("multiple") $compile(ele)(scope) } } }]) // Defining app and controller angular .module("APP", ["checkbox-select"]) .controller("demoCtrl", ["$scope", function ($scope) { var dc = this dc.list = [ "selection1", "selection2", "selection3" ] // Define the selections containers here dc.multipleSelections = [] dc.individualSelections = [] }]) })() label { display: block; } <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="style.css" /> </head> <body ng-app="APP" ng-controller="demoCtrl as dc"> <h1>checkbox-select demo</h1> <h4>Multiple Selections</h4> <label ng-repeat="thing in dc.list"> <input type="checkbox" checkbox-model="dc.multipleSelections" checkbox-value="thing" multiple> {{thing}} </label> <p>dc.multipleSelecitons:- {{dc.multipleSelections}}</p> <h4>Individual Selections</h4> <label ng-repeat="thing in dc.list"> <input type="checkbox" checkbox-model="dc.individualSelections" checkbox-value="thing"> {{thing}} </label> <p>dc.individualSelecitons:- {{dc.individualSelections}}</p> <script data-require="jquery@3.0.0" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script> <script data-require="angular.js@1.5.6" data-semver="1.5.6" src="https://code.angularjs.org/1.5.6/angular.min.js"></script> <script src="script.js"></script> </body> </html>