AngularJS를 사용하여 확인란 값 목록에 어떻게 바인딩합니까?


670

몇 개의 확인란이 있습니다.

<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은 하나의 단일 확인란의 값을 컨트롤러의 변수에만 바인딩 할 수있는 것으로 보입니다.

네 개의 확인란을 컨트롤러의 목록에 바인딩 할 수 있도록 다른 방법이 있습니까?


23
목록이어야합니까? 객체 작업은?겠습니까 <input type='checkbox' ng-model="checkboxes.apple">등의 모델은 다음과 같습니다 { "사과"사실, "오렌지"거짓, "배": 사실, "naartjie"사실}
마크 Rajcok


1
허용 된 답변을 지나쳐보십시오. 거기에 다른 답변 , 내 의견으로는, 훨씬 더 우아한.
Jason Swett

3
naartjie!? 그것은 단지 당신에게 봇을 줄 것입니다! : D
Piotr Kula

1
@ppumkin hehe 이걸 보았습니다. 당신이 맞아 : D
nickponline

답변:


927

이 문제에 접근하는 방법에는 두 가지가 있습니다. 간단한 배열이나 객체 배열을 사용하십시오. 각 솔루션에는 장단점이 있습니다. 다음은 각 사례마다 하나씩입니다.


입력 데이터로 간단한 배열

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/


10
참고로 $ filter를 주입하는 대신 filterFilter를 주입 한 후 다음과 같이 사용할 수 있습니다. return filterFilter ($ scope.fruits, {checked : true}); 내장 및 사용자 정의 필터가 이름 filterNameFilter와 $ 인젝터에 등록 된 ( "FILTERNAME"는 이탤릭체로해야한다) - $ filterProvider 워드 프로세서
마크 Rajcok

24
value="{{fruit.name}}"ng-checked="fruit.checked"NG-모델을 사용하기 때문에, 불필요한 있습니다.
Mark Rajcok

3
모델에서 "checked"를 지정할 필요가 없다는 것을 알았습니다. Angular는 속성을 자동으로 설정합니다 :)
daveoncode

3
엣지 케이스를 더 잘 처리하기 때문에 ng-click 대신 ng-change를 사용해야합니다.
amccausl

2
@ViktorMolokostov 전통적으로 양식을 제출한다면 유용 할 것 입니다. 액션 핸들러 (일부 서버 측 스크립트)에 게시하는 것을 의미합니다. php를 사용하면, 이름이 같은 폼 요소 (대괄호 사용)가 요청 데이터에 배열을 만듭니다. 이렇게하면 선택한 과일을 쉽게 처리 할 수 ​​있습니다.
Yoshi

406

간단한 해결책 :

<div ng-controller="MainCtrl">
  <label ng-repeat="(color,enabled) in colors">
      <input type="checkbox" ng-model="colors[color]" /> {{color}} 
  </label>
  <p>colors: {{colors}}</p>
</div>

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

  app.controller('MainCtrl', function($scope){
      $scope.colors = {Blue: true, Orange: true};
  });
</script>

http://plnkr.co/edit/U4VD61?p=preview


57
@ kolypto-이것은 분명히 답입니다. 나는 물건을 다루는 사람들 (나 같은 사람)을 위해 그것을 다시 썼다 : plnkr.co/edit/cqsADe8lKegsBMgWMyB8?p=preview
Kyle

5
나는 당신이하는 것처럼 그것을하지만, 활성화는 (color,enabled) in colors무엇을합니까?
Sebastian

3
@Sebastian colors은 객체이므로 반복 할 때-쌍을 얻습니다 (key,value).
콜 립토

10
나는이 답변을 매우 좋아하지만! 객체를 데이터 소스로 사용하는 데 큰 문제가 있다고 생각합니다. 즉, 정의에 따라 객체 속성의 순서가 정의되어 있지 않으므로 확인란을 표시 할 때 명확한 순서를 제공 할 수 없습니다. 여전히 +1;)
Yoshi

2
colors이름을 지정해야합니다 isSelected, 훨씬 더 쉽게 읽을 수 있습니다 isSelected[color]이상colors[color]
드미트리 Zaitsev

86
<input type='checkbox' ng-repeat="fruit in fruits"
  ng-checked="checkedFruits.indexOf(fruit) != -1" ng-click="toggleCheck(fruit)">

.

function SomeCtrl ($scope) {
    $scope.fruits = ["apple, orange, pear, naartjie"];
    $scope.checkedFruits = [];
    $scope.toggleCheck = function (fruit) {
        if ($scope.checkedFruits.indexOf(fruit) === -1) {
            $scope.checkedFruits.push(fruit);
        } else {
            $scope.checkedFruits.splice($scope.checkedFruits.indexOf(fruit), 1);
        }
    };
}

2
내가 찾고있는 것이 얼마나 간단한 지 사랑하십시오 (@vitalets 지시문이 훌륭하다는 것을 인정해야하지만). : 나는 Umur의 코드이 바이올린을 만들 수있는 약간 수정 한 jsfiddle.net/samurai_jane/9mwsbfuc
samurai_jane

나는 사무라이 제인의 말을한다! 내가 필요한 것을 보여주는 것이 얼마나 간단했습니다! :)
Francis Rodrigues

81

여기에 당신이 원하는 것을하는 것처럼 보이는 재사용 가능한 작은 지시문이 있습니다. 나는 단순히 그것을 불렀다 checkList. 확인란이 변경되면 배열이 업데이트되고 배열이 변경되면 확인란이 업데이트됩니다.

app.directive('checkList', function() {
  return {
    scope: {
      list: '=checkList',
      value: '@'
    },
    link: function(scope, elem, attrs) {
      var handler = function(setup) {
        var checked = elem.prop('checked');
        var index = scope.list.indexOf(scope.value);

        if (checked && index == -1) {
          if (setup) elem.prop('checked', false);
          else scope.list.push(scope.value);
        } else if (!checked && index != -1) {
          if (setup) elem.prop('checked', true);
          else scope.list.splice(index, 1);
        }
      };

      var setupHandler = handler.bind(null, true);
      var changeHandler = handler.bind(null, false);

      elem.bind('change', function() {
        scope.$apply(changeHandler);
      });
      scope.$watch('list', setupHandler, true);
    }
  };
});

다음은 컨트롤러와 컨트롤러 사용 방법을 보여주는보기입니다.

<div ng-app="myApp" ng-controller='MainController'>
  <span ng-repeat="fruit in fruits">
    <input type='checkbox' value="{{fruit}}" check-list='checked_fruits'> {{fruit}}<br />
  </span>

  <div>The following fruits are checked: {{checked_fruits | json}}</div>

  <div>Add fruit to the array manually:
    <button ng-repeat="fruit in fruits" ng-click='addFruit(fruit)'>{{fruit}}</button>
  </div>
</div>
app.controller('MainController', function($scope) {
  $scope.fruits = ['apple', 'orange', 'pear', 'naartjie'];
  $scope.checked_fruits = ['apple', 'pear'];
  $scope.addFruit = function(fruit) {
    if ($scope.checked_fruits.indexOf(fruit) != -1) return;
    $scope.checked_fruits.push(fruit);
  };
});

단추를 사용하면 배열을 변경하면 확인란도 업데이트됩니다.

마지막으로, Plunker에 적용되는 지시문의 예는 다음과 같습니다. http://plnkr.co/edit/3YNLsyoG4PIBW6Kj7dRK?p=preview


2
고마워 브랜든, 이것은 내가 원하는 것을 정확하게했다. 내가 한 유일한 조정은 jQuery에 대한 종속성을 제거하기 위해 "elem.on ( 'change', function () ..."을 "elem.bind ( 'change', function () ...")으로 변경하는 것입니다. .
조나단 모팻

이것은 매우 깔끔하지만 어떻게 든 ng-disabled를 사용하는 능력을 파괴합니다 :( 어떻게 해결할 수 있습니까?
Nikolaj Dam Larsen

매우 유용합니다! 그리고 소스 목록과 데이터 목록 모두에 대한 배열 대신 객체로 나를 위해 일했습니다!
SteveShaffer

나는 모든 사람에 동의합니다. 이것은 가장 유용하고 의심 할 여지없이 재사용 가능한 것입니다! 좋은 일 감사합니다. :)
maksbd19

2
당신이 AngularJS와> = 1.4.4, 체크에 문제가있는 경우 github.com/angular/angular.js/issues/13037을 : 대체 value: '@'하여value: '=ngValue'
tanguy_k

66

이 스레드의 답변을 바탕으로 모든 경우를 다루는 검사 목록 모델 지시문을 만들었습니다 .

  • 프리미티브의 간단한 배열
  • 객체 배열 (pick id 또는 전체 객체)
  • 객체 속성 반복

주제 시작 사례의 경우 다음과 같습니다.

<label ng-repeat="fruit in ['apple', 'orange', 'pear', 'naartjie']">
    <input type="checkbox" checklist-model="selectedFruits" checklist-value="fruit"> {{fruit}}
</label>

그것은 내가 필요한 것 같습니다. 데이터를 비동기 적으로 가져올 때 사용 방법을 설명 할 수있는 기회가 있습니까? 그 부분은 나에게 혼란 스럽다.
Dan Cancro

데이터를 비동기 적으로 얻은 후에는 위 예제에서 스코프의 checlist 모델을 수정하십시오 selectedFruits.
Adrian Ber

11

문자열 $index을 사용하면 선택한 값의 해시 맵을 사용하는 데 도움 이 될 수 있습니다.

<ul>
    <li ng-repeat="someItem in someArray">
        <input type="checkbox" ng-model="someObject[$index.toString()]" />
    </li>
</ul>

이렇게하면 ng-model 객체가 인덱스를 나타내는 키로 업데이트됩니다.

$scope.someObject = {};

잠시 후 $scope.someObject다음과 같이 보일 것입니다.

$scope.someObject = {
     0: true,
     4: false,
     1: true
};

이 방법은 모든 상황에서 작동하지는 않지만 구현하기 쉽습니다.


이것은 매우 우아한 솔루션이며 내 사례에 적합합니다 (AJAX 사용)
Stephan Ryer

키스 방법을 사용
Geomorillo

8

목록을 사용하지 않은 답변을 수락 했으므로 내 의견 질문에 대한 답변이 "아니요, 목록 일 필요는 없습니다"라고 가정하겠습니다. 또한 샘플 HTML에 "checked"가 있기 때문에 HTML 서버 쪽을 찢어 버릴 수도 있다는 인상을 받았습니다 (ng-model을 사용하여 확인란을 모델링 한 경우에는 필요하지 않음).

어쨌든, 질문을 할 때 염두에두고 HTML 서버 측을 생성한다고 가정합니다.

<div ng-controller="MyCtrl" 
 ng-init="checkboxes = {apple: true, orange: false, pear: true, naartjie: false}">
    <input type="checkbox" ng-model="checkboxes.apple">apple
    <input type="checkbox" ng-model="checkboxes.orange">orange
    <input type="checkbox" ng-model="checkboxes.pear">pear
    <input type="checkbox" ng-model="checkboxes.naartjie">naartjie
    <br>{{checkboxes}}
</div>

ng-init를 사용하면 서버 측에서 생성 된 HTML이 처음에 특정 확인란을 설정할 수 있습니다.

바이올린 .


8

가장 쉬운 해결 방법은 'multiple'이 지정된 'select'를 사용하는 것입니다.

<select ng-model="selectedfruit" multiple ng-options="v for v in fruit"></select>

그렇지 않으면 목록을 처리하기 위해 목록을 처리해야한다고 생각합니다 ( $watch()모델 배열 바인드를 확인란으로 사용하여).


3
그는 체크 박스 목록을 요구하고 있지만 옵션으로 선택하는 것에 대해 말하고 있습니다. 완전히 다릅니다.
CrazySabbath

@CrazySabbath : 그러나 당신은 그가 다른 해결책을 제안한다는 것을 이해하지 못하고 있으며이 답변은 6 명의 다른 사람들이 "대체 해결책"으로서 도움을주었습니다
curiousBoy

5

Yoshi의 대답을 적응시켜 문자열 대신 복잡한 객체를 처리했습니다.

HTML

<div ng-controller="TestController">
    <p ng-repeat="permission in allPermissions">
        <input type="checkbox" ng-checked="selectedPermissions.containsObjectWithProperty('id', permission.id)" ng-click="toggleSelection(permission)" />
        {{permission.name}}
    </p>

    <hr />

    <p>allPermissions: | <span ng-repeat="permission in allPermissions">{{permission.name}} | </span></p>
    <p>selectedPermissions: | <span ng-repeat="permission in selectedPermissions">{{permission.name}} | </span></p>
</div>

자바 스크립트

Array.prototype.indexOfObjectWithProperty = function(propertyName, propertyValue)
{
    for (var i = 0, len = this.length; i < len; i++) {
        if (this[i][propertyName] === propertyValue) return i;
    }

    return -1;
};


Array.prototype.containsObjectWithProperty = function(propertyName, propertyValue)
{
    return this.indexOfObjectWithProperty(propertyName, propertyValue) != -1;
};


function TestController($scope)
{
    $scope.allPermissions = [
    { "id" : 1, "name" : "ROLE_USER" },
    { "id" : 2, "name" : "ROLE_ADMIN" },
    { "id" : 3, "name" : "ROLE_READ" },
    { "id" : 4, "name" : "ROLE_WRITE" } ];

    $scope.selectedPermissions = [
    { "id" : 1, "name" : "ROLE_USER" },
    { "id" : 3, "name" : "ROLE_READ" } ];

    $scope.toggleSelection = function toggleSelection(permission) {
        var index = $scope.selectedPermissions.indexOfObjectWithProperty('id', permission.id);

        if (index > -1) {
            $scope.selectedPermissions.splice(index, 1);
        } else {
            $scope.selectedPermissions.push(permission);
        }
    };
}

실제 예 : http://jsfiddle.net/tCU8v/


1
당신은 <input type="checkbox">포장이나 일치없이 없어야합니다 <label>! 이제 사용자는 확인란 옆에있는 텍스트 대신 실제 확인란을 클릭해야합니다.
Scott

5

또 다른 간단한 지시문은 다음과 같습니다.

var appModule = angular.module("appModule", []);

appModule.directive("checkList", [function () {
return {
    restrict: "A",
    scope: {
        selectedItemsArray: "=",
        value: "@"
    },
    link: function (scope, elem) {
        scope.$watchCollection("selectedItemsArray", function (newValue) {
            if (_.contains(newValue, scope.value)) {
                elem.prop("checked", true);
            } else {
                elem.prop("checked", false);
            }
        });
        if (_.contains(scope.selectedItemsArray, scope.value)) {
            elem.prop("checked", true);
        }
        elem.on("change", function () {
            if (elem.prop("checked")) {
                if (!_.contains(scope.selectedItemsArray, scope.value)) {
                    scope.$apply(
                        function () {
                            scope.selectedItemsArray.push(scope.value);
                        }
                    );
                }
            } else {
                if (_.contains(scope.selectedItemsArray, scope.value)) {
                    var index = scope.selectedItemsArray.indexOf(scope.value);
                    scope.$apply(
                        function () {
                            scope.selectedItemsArray.splice(index, 1);
                        });
                }
            }
            console.log(scope.selectedItemsArray);
        });
    }
};
}]);

컨트롤러 :

appModule.controller("sampleController", ["$scope",
  function ($scope) {
    //#region "Scope Members"
    $scope.sourceArray = [{ id: 1, text: "val1" }, { id: 2, text: "val2" }];
    $scope.selectedItems = ["1"];
    //#endregion
    $scope.selectAll = function () {
      $scope.selectedItems = ["1", "2"];
  };
    $scope.unCheckAll = function () {
      $scope.selectedItems = [];
    };
}]);

그리고 HTML :

<ul class="list-unstyled filter-list">
<li data-ng-repeat="item in sourceArray">
    <div class="checkbox">
        <label>
            <input type="checkbox" check-list selected-items-array="selectedItems" value="{{item.id}}">
            {{item.text}}
        </label>
    </div>
</li>

나는 또한 Plunker를 포함하고 있습니다 : http://plnkr.co/edit/XnFtyij4ed6RyFwnFN6V?p=preview


5

다음 솔루션은 좋은 옵션처럼 보입니다.

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

컨트롤러 모델 값 fruits은 다음과 같습니다

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

이 예제를 더 많이 볼수록 배열을 객체 배열에 매핑해야합니다.
Winnemucca

4

모든 코드를 작성할 필요는 없습니다. AngularJS는 ngTrueValue 및 ngFalseValue를 사용하여 모델과 확인란을 동기화 상태로 유지합니다.

여기 코드 펜 : http://codepen.io/paulbhartzog/pen/kBhzn

코드 스 니펫 :

<p ng-repeat="item in list1" class="item" id="{{item.id}}">
  <strong>{{item.id}}</strong> <input name='obj1_data' type="checkbox" ng-model="list1[$index].data" ng-true-value="1" ng-false-value="0"> Click this to change data value below
</p>
<pre>{{list1 | json}}</pre>

이것은 OP가 요구하는 것이 아닙니다.
bfontaine

체크 박스를 목록에 바인딩하는 것이 요청 된 것입니다. 어플리케이션에 맞게 어레이를 수정할 수 있습니다. 요점은 확인란이 바인딩되어 있다는 것입니다. ngTrueValue 및 ngFalseValue를 사용하여 이름과 같은 다른 속성 만 나열하는 두 번째 배열에 매핑 할 수도 있습니다.
Paul B. Hartzog

OP는 모든 값의 목록이 아닌 확인 된 값 목록을 확인하고 선택하지 않기를 원합니다.
bfontaine

4

확인란의 목록을 효과적으로 관리하는이 지시어를 확인하십시오. 나는 그것이 당신을 위해 작동하기를 바랍니다. 체크리스트 모델


4

어레이에서 직접 작업하고 ng-model을 동시에 사용하는 방법이 있습니다. ng-model-options="{ getterSetter: true }" .

트릭은 ng-model에서 getter / setter 함수를 사용하는 것입니다. 이런 식으로 배열을 실제 모델로 사용하고 입력 모델에서 부울을 "가짜"만들 수 있습니다.

<label ng-repeat="fruitName in ['apple', 'orange', 'pear', 'naartjie']">
  <input
    type="checkbox"
    ng-model="fruitsGetterSetterGenerator(fruitName)"
    ng-model-options="{ getterSetter: true }"
  > {{fruitName}}
</label>

$scope.fruits = ['apple', 'pear']; // pre checked

$scope.fruitsGetterSetterGenerator = function(fruitName){
    return function myGetterSetter(nowHasFruit){
        if (nowHasFruit !== undefined){

            // Setter
            fruitIndex = $scope.fruits.indexOf(fruit);
            didHaveFruit = (fruitIndex !== -1);
            mustAdd = (!didHaveFruit && nowHasFruit);
            mustDel = (didHaveFruit && !nowHasFruit);
            if (mustAdd){
                $scope.fruits.push(fruit);
            }
            if (mustDel){
                $scope.fruits.splice(fruitIndex, 1);
            }
        }
        else {
            // Getter
            return $scope.user.fruits.indexOf(fruit) !== -1;
        }
    }
}

경고 배열이 myGetterSetter여러 번 호출 될 정도로 큰 경우이 방법을 사용하지 않아야합니다 .

이에 대한 자세한 내용은 https://docs.angularjs.org/api/ng/directive/ngModelOptions를 참조 하십시오 .


3

나는 요시의 대답을 좋아한다. 여러 목록에 대해 동일한 기능을 사용할 수 있도록 개선했습니다.

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


<label ng-repeat="veggieName in veggies">
<input
type="checkbox"
name="selectedVeggies[]"
value="{{veggieName}}"
ng-checked="veggieSelection.indexOf(veggieName) > -1"
ng-click="toggleSelection(veggieName, veggieSelection)"> {{veggieName}}
</label>



app.controller('SimpleArrayCtrl', ['$scope', function SimpleArrayCtrl($scope) {
  // fruits
  $scope.fruits = ['apple', 'orange', 'pear', 'naartjie'];
  $scope.veggies = ['lettuce', 'cabbage', 'tomato']
  // selected fruits
  $scope.selection = ['apple', 'pear'];
  $scope.veggieSelection = ['lettuce']
  // toggle selection for a given fruit by name
  $scope.toggleSelection = function toggleSelection(selectionName, listSelection) {
    var idx = listSelection.indexOf(selectionName);

    // is currently selected
    if (idx > -1) {
      listSelection.splice(idx, 1);
    }

    // is newly selected
    else {
      listSelection.push(selectionName);
    }
  };
}]);

http://plnkr.co/edit/KcbtzEyNMA8s1X7Hja8p?p=preview


3

같은 양식에 여러 개의 확인란이있는 경우

컨트롤러 코드

vm.doYouHaveCheckBox = ['aaa', 'ccc', 'bbb'];
vm.desiredRoutesCheckBox = ['ddd', 'ccc', 'Default'];
vm.doYouHaveCBSelection = [];
vm.desiredRoutesCBSelection = [];

코드보기

<div ng-repeat="doYouHaveOption in vm.doYouHaveCheckBox">
    <div class="action-checkbox">
        <input id="{{doYouHaveOption}}" type="checkbox" value="{{doYouHaveOption}}" ng-checked="vm.doYouHaveCBSelection.indexOf(doYouHaveOption) > -1" ng-click="vm.toggleSelection(doYouHaveOption,vm.doYouHaveCBSelection)" />
        <label for="{{doYouHaveOption}}"></label>
        {{doYouHaveOption}}
    </div>
</div>

<div ng-repeat="desiredRoutesOption in vm.desiredRoutesCheckBox">
     <div class="action-checkbox">
          <input id="{{desiredRoutesOption}}" type="checkbox" value="{{desiredRoutesOption}}" ng-checked="vm.desiredRoutesCBSelection.indexOf(desiredRoutesOption) > -1" ng-click="vm.toggleSelection(desiredRoutesOption,vm.desiredRoutesCBSelection)" />
          <label for="{{desiredRoutesOption}}"></label>
          {{desiredRoutesOption}}
     </div>
</div>        

3

위의 요시 게시물에서 영감을 얻었습니다. 여기는 plnkr입니다 입니다.

(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>


3

내 다른 게시물을 기반으로 여기 재사용 가능한 지시문을 작성했습니다.

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>


3

HTML에서 (확인란이 테이블의 모든 행의 첫 번째 열에 있다고 가정).

<tr ng-repeat="item in fruits">
    <td><input type="checkbox" ng-model="item.checked" ng-click="getChecked(item)"></td>
    <td ng-bind="fruit.name"></td>
    <td ng-bind="fruit.color"></td>
    ...
</tr>

에서 controllers.js파일 :

// The data initialization part...
$scope.fruits = [
    {
      name: ....,
      color:....
    },
    {
      name: ....,
      color:....
    }
     ...
    ];

// The checked or not data is stored in the object array elements themselves
$scope.fruits.forEach(function(item){
    item.checked = false;
});

// The array to store checked fruit items
$scope.checkedItems = [];

// Every click on any checkbox will trigger the filter to find checked items
$scope.getChecked = function(item){
    $scope.checkedItems = $filter("filter")($scope.fruits,{checked:true});
};

3

여기 또 다른 해결책이 있습니다. 내 솔루션의 거꾸로 :

  • 추가 시계가 필요하지 않습니다 (성능에 영향을 줄 수 있음)
  • 깨끗하게 유지하기 위해 컨트롤러에 코드가 필요하지 않습니다.
  • 코드는 여전히 약간 짧습니다
  • 지시문 일 뿐이므로 여러 곳에서 재사용하기 위해 코드가 거의 필요하지 않습니다.

지시어는 다음과 같습니다.

function ensureArray(o) {
    var lAngular = angular;
    if (lAngular.isArray(o) || o === null || lAngular.isUndefined(o)) {
        return o;
    }
    return [o];
}

function checkboxArraySetDirective() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
            var name = attrs.checkboxArraySet;

            ngModel.$formatters.push(function(value) {
                return (ensureArray(value) || []).indexOf(name) >= 0;
            });

            ngModel.$parsers.push(function(value) {
                var modelValue = ensureArray(ngModel.$modelValue) || [],
                    oldPos = modelValue.indexOf(name),
                    wasSet = oldPos >= 0;
                if (value) {
                    if (!wasSet) {
                        modelValue = angular.copy(modelValue);
                        modelValue.push(name);
                    }
                } else if (wasSet) {
                    modelValue = angular.copy(modelValue);
                    modelValue.splice(oldPos, 1);
                }
                return modelValue;
            });
        }
    }
}

마지막에 다음과 같이 사용하십시오.

<input ng-repeat="fruit in ['apple', 'banana', '...']" type="checkbox" ng-model="fruits" checkbox-array-set="{{fruit}}" />

그리고 그것이 전부입니다. 유일한 추가는 checkbox-array-set속성입니다.


3

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))하여 선택한 항목을 확인할 수 있습니다.


Perfect! ... 이것은 객체가 아닌 배열을 사용하는 가장 간단한 솔루션입니다.
Mario Campa

3
Jquery와 Angular를 결합하지
마십시오

선택한 어레이에 구멍이 생깁니다. 이 게시물
Vikas Gautam

2
  <div ng-app='app' >
    <div ng-controller='MainCtrl' >
       <ul> 
       <li ng-repeat="tab in data">
         <input type='checkbox' ng-click='change($index,confirm)' ng-model='confirm' />
         {{tab.name}} 
         </li>
     </ul>
    {{val}}
   </div>
 </div>


var app = angular.module('app', []);
 app.controller('MainCtrl',function($scope){
 $scope.val=[];
  $scope.confirm=false;
  $scope.data=[
   {
     name:'vijay'
     },
    {
      name:'krishna'
    },{
      name:'Nikhil'
     }
    ];
    $scope.temp;
   $scope.change=function(index,confirm){
     console.log(confirm);
    if(!confirm){
     ($scope.val).push($scope.data[index]);   
    }
    else{
    $scope.temp=$scope.data[index];
        var d=($scope.val).indexOf($scope.temp);
        if(d!=undefined){
         ($scope.val).splice(d,1);
        }    
       }
     }   
   })

1

이것을 확인하십시오 : checklist-model .

JavaScript 배열 및 객체와 함께 작동하며 ng-repeat없이 정적 HTML 확인란을 사용할 수 있습니다

<label><input type="checkbox" checklist-model="roles" value="admin"> Administrator</label>
<label><input type="checkbox" checklist-model="roles" value="customer"> Customer</label>
<label><input type="checkbox" checklist-model="roles" value="guest"> Guest</label>
<label><input type="checkbox" checklist-model="roles" value="user"> User</label>

그리고 JavaScript 측면 :

var app = angular.module("app", ["checklist-model"]);
app.controller('Ctrl4a', function($scope) {
    $scope.roles = [];
});

1

간단한 HTML 전용 방법 :

<input type="checkbox"
       ng-checked="fruits.indexOf('apple') > -1"
       ng-click="fruits.indexOf('apple') > -1 ? fruits.splice(fruits.indexOf('apple'), 1) : fruits.push('apple')">
<input type="checkbox"
       ng-checked="fruits.indexOf('orange') > -1"
       ng-click="fruits.indexOf('orange') > -1 ? fruits.splice(fruits.indexOf('orange'), 1) : fruits.push('orange')">
<input type="checkbox"
       ng-checked="fruits.indexOf('pear') > -1"
       ng-click="fruits.indexOf('pear') > -1 ? fruits.splice(fruits.indexOf('pear'), 1) : fruits.push('pear')">
<input type="checkbox"
       ng-checked="fruits.indexOf('naartjie') > -1"
       ng-click="fruits.indexOf('apple') > -1 ? fruits.splice(fruits.indexOf('apple'), 1) : fruits.push('naartjie')">


1

사용 이 예 @Umur Kontacı의를, 나는 편집 페이지와 같은 다른 객체 / 배열을 통해 캐치 선택한 데이터를 사용하여 생각합니다.

데이터베이스에서 캐치 옵션

여기에 이미지 설명을 입력하십시오

몇 가지 옵션을 토글

여기에 이미지 설명을 입력하십시오

예를 들어 아래의 모든 색상이 json입니다.

{
    "colors": [
        {
            "id": 1,
            "title": "Preto - #000000"
        },
        {
            "id": 2,
            "title": "Azul - #005AB1"
        },
        {
            "id": 3,
            "title": "Azul Marinho - #001A66"
        },
        {
            "id": 4,
            "title": "Amarelo - #FFF100"
        },
        {
            "id": 5,
            "title": "Vermelho - #E92717"
        },
        {
            "id": 6,
            "title": "Verde - #008D2F"
        },
        {
            "id": 7,
            "title": "Cinza - #8A8A8A"
        },
        {
            "id": 8,
            "title": "Prata - #C8C9CF"
        },
        {
            "id": 9,
            "title": "Rosa - #EF586B"
        },
        {
            "id": 10,
            "title": "Nude - #E4CAA6"
        },
        {
            "id": 11,
            "title": "Laranja - #F68700"
        },
        {
            "id": 12,
            "title": "Branco - #FFFFFF"
        },
        {
            "id": 13,
            "title": "Marrom - #764715"
        },
        {
            "id": 14,
            "title": "Dourado - #D9A300"
        },
        {
            "id": 15,
            "title": "Bordo - #57001B"
        },
        {
            "id": 16,
            "title": "Roxo - #3A0858"
        },
        {
            "id": 18,
            "title": "Estampado "
        },
        {
            "id": 17,
            "title": "Bege - #E5CC9D"
        }
    ]
}

그리고 array하나의 객체를 가지고 있고 object두 개 이상의 객체 데이터를 포함하는 두 가지 유형의 데이터 객체 :

  • 데이터베이스에서 선택된 두 항목 :

    [{"id":12,"title":"Branco - #FFFFFF"},{"id":16,"title":"Roxo - #3A0858"}]
  • 데이터베이스에서 선택된 하나의 항목 :

    {"id":12,"title":"Branco - #FFFFFF"}

그리고 여기, 내 자바 스크립트 코드 :

/**
 * Add this code after catch data of database.
 */

vm.checkedColors = [];
var _colorObj = vm.formData.color_ids;
var _color_ids = [];

if (angular.isObject(_colorObj)) {
    // vm.checkedColors.push(_colorObj);
    _color_ids.push(_colorObj);
} else if (angular.isArray(_colorObj)) {
    angular.forEach(_colorObj, function (value, key) {
        // vm.checkedColors.push(key + ':' + value);
        _color_ids.push(key + ':' + value);
    });
}

angular.forEach(vm.productColors, function (object) {
    angular.forEach(_color_ids, function (color) {
        if (color.id === object.id) {
            vm.checkedColors.push(object);
        }
    });
});

/**
 * Add this code in your js function initialized in this HTML page
 */
vm.toggleColor = function (color) {
    console.log('toggleColor is: ', color);

    if (vm.checkedColors.indexOf(color) === -1) {
        vm.checkedColors.push(color);
    } else {
        vm.checkedColors.splice(vm.checkedColors.indexOf(color), 1);
    }
    vm.formData.color_ids = vm.checkedColors;
};

내 HTML 코드 :

<div class="checkbox" ng-repeat="color in productColors">
    <label>
        <input type="checkbox"
               ng-checked="checkedColors.indexOf(color) != -1"
               ng-click="toggleColor(color)"/>
        <% color.title %>
    </label>
</div>

<p>checkedColors Output:</p>
<pre><% checkedColors %></pre>

[편집] 아래 리팩토링 된 코드 :

function makeCheckedOptions(objectOptions, optionObj) {
    var checkedOptions = [];
    var savedOptions = [];

    if (angular.isObject(optionObj)) {
        savedOptions.push(optionObj);
    } else if (angular.isArray(optionObj)) {
        angular.forEach(optionObj, function (value, key) {
            savedOptions.push(key + ':' + value);
        });
    }

    angular.forEach(objectOptions, function (object) {
        angular.forEach(savedOptions, function (color) {
            if (color.id === object.id) {
                checkedOptions.push(object);
            }
        });
    });

    return checkedOptions;
}

다음과 같이 새로운 메소드를 호출하십시오.

vm.checkedColors = makeCheckedOptions(productColors, vm.formData.color_ids);

그게 다야!


1

컨트롤러에 배열을 넣었습니다.

$scope.statuses = [{ name: 'Shutdown - Reassessment Required' },
    { name: 'Under Construction' },
    { name: 'Administrative Cancellation' },
    { name: 'Initial' },
    { name: 'Shutdown - Temporary' },
    { name: 'Decommissioned' },
    { name: 'Active' },
    { name: 'SO Shutdown' }]

마크 업에 다음과 같은 것을 넣었습니다.

<div ng-repeat="status in $scope.statuses">
   <input type="checkbox" name="unit_status" ng-model="$scope.checkboxes[status.name]"> {{status.name}}
   <br>                        
</div>
{{$scope.checkboxes}}

출력은 다음과 같았습니다. 컨트롤러에서 방금 true 또는 false인지 확인해야했습니다. 확인 된 경우 true, 확인되지 않은 경우 부재 / 거짓.

{
"Administrative Cancellation":true,
"Under Construction":true,
"Shutdown - Reassessment Required":true,
"Decommissioned":true,
"Active":true
}

도움이 되었기를 바랍니다.


0

다음 방법이 중첩 된 ng-repeats에 더 명확하고 유용하다고 생각합니다. Plunker 에서 확인하십시오 .

이 스레드에서 인용 :

<html ng-app="plunker">
    <head>
        <title>Test</title>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
    </head>

    <body ng-controller="MainCtrl">
        <div ng-repeat="tab in mytabs">

            <h1>{{tab.name}}</h1>
            <div ng-repeat="val in tab.values">
                <input type="checkbox" ng-change="checkValues()" ng-model="val.checked"/>
            </div>
        </div>

        <br>
        <pre> {{selected}} </pre>

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

                app.controller('MainCtrl', function ($scope,$filter) {
                    $scope.mytabs = [
             {
                 name: "tab1",
                 values: [
                     { value: "value1",checked:false },
                     { value: "value2", checked: false },
                     { value: "value3", checked: false },
                     { value: "value4", checked: false }
                 ]
             },
             {
                 name: "tab2",
                 values: [
                     { value: "value1", checked: false },
                     { value: "value2", checked: false },
                     { value: "value3", checked: false },
                     { value: "value4", checked: false }
                 ]
             }
                    ]
                    $scope.selected = []
                    $scope.checkValues = function () {
                        angular.forEach($scope.mytabs, function (value, index) {
                         var selectedItems = $filter('filter')(value.values, { checked: true });
                         angular.forEach(selectedItems, function (value, index) {
                             $scope.selected.push(value);
                         });

                        });
                    console.log($scope.selected);
                    };
                });
        </script>
    </body>
</html>

0

다음은 동일한 http://jsfiddle.net/techno2mahi/Lfw96ja6/에 대한 jsFillde 링크입니다 .

http://vitalets.github.io/checklist-model/ 에서 다운로드 할 수있는 지시문을 사용합니다 .

응용 프로그램에서이 기능을 자주 필요로하므로 지시문을 갖는 것이 좋습니다.

코드는 다음과 같습니다.

HTML :

<div class="container">
    <div class="ng-scope" ng-app="app" ng-controller="Ctrl1">
        <div class="col-xs-12 col-sm-6">
            <h3>Multi Checkbox List Demo</h3>
            <div class="well">  <!-- ngRepeat: role in roles -->
                <label ng-repeat="role in roles">
                    <input type="checkbox" checklist-model="user.roles" checklist-value="role"> {{role}}
                </label>
            </div>

            <br>
            <button ng-click="checkAll()">check all</button>
            <button ng-click="uncheckAll()">uncheck all</button>
            <button ng-click="checkFirst()">check first</button>
            <div>
                <h3>Selected User Roles </h3>
                <pre class="ng-binding">{{user.roles|json}}</pre>
            </div>

            <br>
            <div><b/>Provided by techno2Mahi</b></div>
        </div>

자바 스크립트

var app = angular.module("app", ["checklist-model"]);
app.controller('Ctrl1', function($scope) {
  $scope.roles = [
    'guest',
    'user',
    'customer',
    'admin'
  ];
  $scope.user = {
    roles: ['user']
  };
  $scope.checkAll = function() {
    $scope.user.roles = angular.copy($scope.roles);
  };
  $scope.uncheckAll = function() {
    $scope.user.roles = [];
  };
  $scope.checkFirst = function() {
    $scope.user.roles.splice(0, $scope.user.roles.length);
    $scope.user.roles.push('guest');
  };
});

HTML의 형식이 올바르지 않습니다 . <div>닫기 보다 여는 태그가 더 많습니다 </div>. 당신이 뭔가를 남겼습니까?
피터 Mortensen

0

내 아기를보십시오 :

**

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 모델의 경우 선택한 모든 입력의 문자열을 반환합니다.

<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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.