AngularJS ile onay kutusu değerleri listesine nasıl bağlanırım?


670

Birkaç onay kutum var:

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

Her ne zaman bir onay kutusu değiştiğinde denetleyici kontrol edilen tüm değerlerin bir listesini tutar, örneğin, benim denetleyicisindeki bir listeye bağlamak istiyorum ['apple', 'pear'].

ng-model, tek bir onay kutusunun değerini denetleyicideki bir değişkene bağlayabiliyor gibi görünüyor.

Dört onay kutusunu denetleyicideki bir listeye bağlayabilmemin başka bir yolu var mı?


23
Bir liste olmalı mı? Bir nesne işe <input type='checkbox' ng-model="checkboxes.apple">yarar mı ?: vb. Model şöyle olurdu: {"elma": doğru, "turuncu": yanlış, "armut": doğru, "naartjie": doğru}
Mark Rajcok


1
Kabul edilen cevabı geçtiğinizden emin olun. Orada başka cevap , benim görüşüme göre, çok daha zarif.
Jason Swett

3
naartjie!? Bu sadece size boet veriyor! : D
Piotr Kula

1
@ppumkin hehe bunu daha yeni gördü. Haklısın: D
nickponline

Yanıtlar:


927

Bu soruna yaklaşmanın iki yolu vardır. Basit bir dizi veya bir nesne dizisi kullanın. Her çözümün artıları ve eksileri vardır. Aşağıda her vaka için bir tane bulacaksınız.


Giriş verisi olarak basit bir dizi ile

HTML şöyle görünebilir:

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

Ve uygun denetleyici kodu:

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);
    }
  };
}]);

Artıları : Basit veri yapısı ve isme göre geçiş yapmak kolaydır

Eksileri : İki liste (giriş ve seçim) yönetilmesi gerektiğinden ekleme / kaldırma zahmetlidir


Giriş verisi olarak bir nesne dizisiyle

HTML şöyle görünebilir:

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

Ve uygun denetleyici kodu:

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);
}]);

Artıları : Ekleme / kaldırma çok kolay

Eksileri : Biraz daha karmaşık veri yapısı ve isme göre geçiş yapmak hantaldır veya yardımcı bir yöntem gerektirir


Demo : http://jsbin.com/ImAqUC/1/


10
FYI, $ filter enjekte etmek yerine filterFilter enjekte edebilir ve ardından aşağıdaki gibi kullanabilirsiniz: return filterFilter ($ scope.fruits, {işaretli: true}); Yerleşik ve özel filtreler adı filterNameFilter ile $ enjektör ile kayıtlıdır ( "filterName" italik olmalıdır) - $ FilterProvider dokümanlar
Mark Rajcok

24
value="{{fruit.name}}"ve ng-checked="fruit.checked"ng model kullanıldığı için, gerek kalmaz.
Mark Rajcok

3
Modelde "işaretli" belirtmeye gerek olmadığını fark ettim, Angular özelliği otomatik olarak ayarlayacak :)
daveoncode

3
Kenar durumları daha iyi olduğu için ng-click yerine ng-change kullanmalıdır.
amccausl

2
@ViktorMolokostov Formu geleneksel olarak göndermek olsaydı, bu sadece yararlı olurdu . Bu, eylem işleyicisine (bazı sunucu tarafı komut dosyası) gönderme anlamına gelir. Php ile, böyle bir ada sahip bir form öğesi (köşeli parantez kullanılarak) istek verilerinde bir dizi oluşturur. Bu şekilde seçilen meyveleri kolayca işleyebilirsiniz.
Yoshi

406

Basit bir çözüm:

<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 - bu kesinlikle cevap. Nesnelerle çalışan insanlar (benim gibi) için yeniden yazdım
Kyle

5
Bunu senin gibi yapıyorum ama etkin olan ne yapıyor (color,enabled) in colors?
Sebastian

3
@Sebastian, çünkü colorsbir nesne, onu yinelediğinizde - çiftleri alırsınız (key,value).
kolypto

10
Bu cevabı çok sevmem gerçi! Veri kaynağı olarak nesneleri kullanmada büyük bir sorun olduğunu düşünüyorum. Diğer bir deyişle, tanım gereği nesne özelliklerinin sırası tanımsız olduğundan, onay kutularını görüntülerken kesin bir sipariş verilemez. Hala +1;)
Yoshi

2
colorsadlı olmalıdır isSelected, okumak çok daha kolaydır isSelected[color]dahacolors[color]
Dmitri Zaitsev'in

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
Ne kadar basit aşk, tam olarak ne arıyorum (@vitalets yönergesi şaşırtıcı olduğunu itiraf etmeliyim). Bu kemanı oluşturmak için Umur'un kodunu biraz değiştirdim: jsfiddle.net/samurai_jane/9mwsbfuc
samurai_jane

Samuray Jane madeninin sözlerini ben yaparım! Sadece ihtiyacım olanı göstermek ne kadar basitti! :)
Francis Rodrigues

81

İşte yapmak istediğinizi yapan hızlı bir yeniden kullanılabilir direktif. Basitçe aradım checkList. Onay kutuları değiştiğinde diziyi günceller ve dizi değiştiğinde onay kutularını güncelleştirir.

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);
    }
  };
});

İşte bir denetleyici ve onu nasıl kullanabileceğinizi gösteren bir görünüm.

<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);
  };
});

(Düğmeler, diziyi değiştirmenin onay kutularını da güncelleyeceğini gösterir.)

Son olarak, Plunker ile ilgili yürürlükte olan direktifin bir örneği: http://plnkr.co/edit/3YNLsyoG4PIBW6Kj7dRK?p=preview


2
Teşekkürler Brandon, bu tam olarak istediğimi yaptı (ve diğer soruların aksine, sorunun da ne istediğini). Yaptığım tek değişiklik, jQuery'ye bağımlılığı kaldırmak için "elem.on ('change', function () ..." ifadenizi "elem.bind ('change', function () ..." olarak değiştirmekti. .
Jonathan Moffatt

Bu oldukça düzgün, ama bir şekilde ng-engelli kullanma yeteneğimi yok ediyor :( Bunu
çözebilmemin

Süper kullanışlı! Ve hatta benim için hem kaynak listesi hem de veri listesi için diziler yerine nesnelerle çalıştı!
SteveShaffer

Herkese katılıyorum. Bu en yararlı ve şüphesiz yeniden kullanılabilir bir !! İyi çalışma için teşekkürler. :)
maksbd19

2
Eğer angularjs> = 1.4.4, çek ile ilgili sorunlar yaşıyorsanız github.com/angular/angular.js/issues/13037 : yerine value: '@'görevalue: '=ngValue'
tanguy_k

66

Bu konudaki cevaplara dayanarak tüm vakaları kapsayan bir kontrol listesi modeli direktifi oluşturdum :

  • basit ilkel dizi
  • nesne dizisi (seçim kimliği veya tüm nesne)
  • nesne özellikleri yinelemesi

Konu başlangıç ​​durumu için:

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

İhtiyacım olana benziyor. Verileri eşzamansız olarak alırken nasıl kullanacağınızı açıklayabilme şansınız var mı? Bu kısım benim için kafa karıştırıcı.
Dan Cancro

Verileri eşzamansız olarak aldıktan sonra, yukarıdaki örnekte kapsamda checlist modelini değiştirmeniz yeterlidir selectedFruits.
Adrian Ber

11

Bir dizeyi $indexkullanmak, seçilen değerlerin hashmap'inin kullanılmasına yardımcı olabilir:

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

Bu şekilde ng-model nesnesi, dizini temsil eden anahtarla güncellenir.

$scope.someObject = {};

Bir süre sonra $scope.someObjectşöyle görünmelidir:

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

Bu yöntem tüm durumlar için işe yaramaz, ancak uygulanması kolaydır.


Bu çok zarif bir çözüm ve benim
durumuma

öpücük yöntemini kullanır
Geomorillo

8

Bir listenin kullanılmadığı bir yanıtı kabul ettiğiniz için, yorum sorumun cevabının "Hayır, liste olması gerekmediğini" varsayacağım. Örnek HTML'nizde "işaretli" bulunduğundan (HTML kutularını işaretlemek için gerekli olmasa da bu gerekli olmayacaktır).

Her neyse, soruyu sorduğumda, HTML sunucusu tarafını oluşturduğunuzu varsayarak aklımda olan şey:

<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, sunucu tarafında oluşturulan HTML'nin başlangıçta belirli onay kutularını ayarlamasına izin verir.

Keman .


8

Bence en kolay geçici çözüm 'çoklu' belirtilen 'select' kullanmak olacaktır:

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

Aksi takdirde, listeyi oluşturmak için listeyi işlemeniz gerektiğini düşünüyorum ( $watch()onay kutusunu işaretleyerek model dizisini bağlayarak).


3
Bir onay kutusu listesi istiyor, ancak yine de seçeneklerle seçim yapmasını söylüyorsun. Bu tamamen farklı.
CrazySabbath

@CrazySabbath: Yine de alternatif bir çözüm önerdiğini anlamıyorsunuz ve bu cevap 6 kişiye "alternatif çözüm" olarak yardımcı oldu
curiousBoy

5

Yoshi'nin kabul edilen cevabını karmaşık nesnelerle (dizeler yerine) başa çıkmak için uyarladım.

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>

JavaScript

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);
        }
    };
}

Çalışma örneği: http://jsfiddle.net/tCU8v/


1
Hiç <input type="checkbox">bir sargı veya eşleştirme olmadan bir olmamalıdır <label>! Artık kullanıcılarınız, onay kutusunun yanındaki metin yerine asıl onay kutusunu tıklatmalı, bu da çok daha zor ve kullanılabilirliği kötü.
Scott

5

Başka bir basit yönerge şöyle olabilir:

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);
        });
    }
};
}]);

Kontrol eden, denetleyici:

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 = [];
    };
}]);

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

Ben de bir Plunker dahil: http://plnkr.co/edit/XnFtyij4ed6RyFwnFN6V?p=preview


5

Aşağıdaki çözüm iyi bir seçenek gibi görünüyor,

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

Ve kontrolör modelinde değer fruitsböyle olacak

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

daha fazla ben bu örneklere bakıyorum ben nesneleri bir dizi içine benim dizi eşleştirmek zorunda kalacak gibi görünüyor.
Winnemucca

4

Tüm bu kodu yazmak zorunda değilsiniz. AngularJS, ngTrueValue ve ngFalseValue kullanarak modeli ve onay kutularını senkronize tutar

Buradan kodu açın: http://codepen.io/paulbhartzog/pen/kBhzn

Kod snippet'i:

<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'nin istediği bu değil.
bfontaine

Onay kutularını bir listeye bağlamak, sorulan ve yaptığım şeydir. Dizi, uygulamaya uyacak şekilde değiştirilebilir. Önemli olan onay kutularının bağlı olmasıdır. ngTrueValue ve ngFalseValue, yalnızca adlar gibi diğer nitelikleri listeleyen ikinci bir diziye eşlemek için de kullanılabilir.
Paul B. Hartzog

OP, kontrol edilen ve işaretlenmeyen tüm değerlerin listesini değil, kontrol edilen değerlerin bir listesini ister.
bfontaine


4

Doğrudan dizi üzerinde çalışmanın ve ng-modelini aynı anda kullanmanın bir yolu vardır ng-model-options="{ getterSetter: true }".

İşin püf noktası, ng-modelinizde bir alıcı / ayarlayıcı işlevi kullanmaktır. Bu şekilde bir diziyi gerçek modeliniz olarak kullanabilir ve girdinin modelindeki booleanları "taklit edebilirsiniz":

<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;
        }
    }
}

CAVEAT Dizileriniz myGetterSetterbirçok kez çağrılacak kadar büyükse bu yöntemi kullanmamalısınız .

Bununla ilgili daha fazla bilgi için bkz. Https://docs.angularjs.org/api/ng/directive/ngModelOptions .


3

Yoshi'nin cevabını seviyorum. Birden fazla liste için aynı işlevi kullanabilmeniz için geliştirdim.

<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

Aynı formda birden fazla onay kutunuz varsa

Denetleyici kodu

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

Kodu görüntüle

<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

Yoshi'nin yukarıdaki görevinden ilham aldı. İşte 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

Buradaki diğer gönderime dayanarak, yeniden kullanılabilir bir direktif hazırladım.

Check out GitHub depo

(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'de (onay kutularının bir tablodaki her satırın ilk sütununda olduğunu varsayalım).

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

In controllers.jsdosyası:

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

İşte başka bir çözüm. Çözümümün ters tarafı:

  • Herhangi bir ek saate ihtiyaç duymaz (performans üzerinde etkisi olabilir)
  • Denetleyicide temiz tutmak için herhangi bir kod gerektirmez
  • Kod hala biraz kısa
  • Sadece bir direktif olduğu için birden fazla yerde yeniden kullanmak çok az kod gerektirir

İşte yönerge:

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;
            });
        }
    }
}

Sonunda sadece şu şekilde kullanın:

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

Ve hepsi bu kadar. Tek ekleme checkbox-array-setözniteliğidir.


3

AngularJS ve jQuery'yi birleştirebilirsiniz. Örneğin $scope.selected = [];, denetleyicide bir dizi tanımlamanız gerekir .

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

Seçilen öğelere sahip bir dizi alabilirsiniz. Yöntemi kullanarak alert(JSON.stringify($scope.selected)), seçilen öğeleri kontrol edebilirsiniz.


Mükemmel! ... bu bir nesneyi değil bir dizi kullanarak en basit çözüm
Mario Campa

3
Jquery ve Açısal
Jens Alenius'u

Bu, seçilen Dizide deliklere yol açacaktır. Bu kontrol yazı
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

Şuna bir bakın: kontrol listesi modeli .

JavaScript dizileri ve nesnelerle çalışır ve tekrarlama yapmadan statik HTML onay kutularını kullanabilir

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

Ve JavaScript tarafı:

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

1

Basit bir HTML yapmanın tek yolu:

<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

Bu örneği kullanma @Umur Kontacı, ben bir düzenleme sayfası gibi başka bir nesne / dizinin boyunca yakalamak seçilen verilere kullanarak düşünüyorum.

Veritabanındaki yakalama seçenekleri

resim açıklamasını buraya girin

Bazı seçenekleri aç / kapat

resim açıklamasını buraya girin

Örneğin, aşağıdaki tüm renkler 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"
        }
    ]
}

Ve arraybir nesne objectiçeren ve iki / daha fazla nesne verisi içeren 2 tür veri nesnesi :

  • Seçilen iki öğe veritabanında yakalandı:

    [{"id":12,"title":"Branco - #FFFFFF"},{"id":16,"title":"Roxo - #3A0858"}]
  • Seçilen bir öğe veritabanında yakalandı:

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

Ve burada, javascript kodum:

/**
 * 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 kodum:

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

[Düzenle] Aşağıdaki yeniden düzenlenmiş kod:

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;
}

Ve aşağıdaki gibi yeni yöntemi çağırın:

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

Bu kadar!


1

Denetleyiciye bir dizi koydum.

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

İşaretlemeye aşağıdaki gibi bir şey koydum

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

Çıktı aşağıdaki gibiydi, kontrolörde sadece doğru veya yanlış olup olmadığını kontrol etmem gerekiyordu; işaretli için doğru, işaretlenmemiş için yok / yanlış.

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

Bu yardımcı olur umarım.


0

Aşağıdaki yol, iç içe ng tekrarları için daha açık ve yararlı olduğunu düşünüyorum. Plunker'da kontrol edin .

Bu konudan alıntı :

<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

İşte bunun için jsFillde bağlantısı, http://jsfiddle.net/techno2mahi/Lfw96ja6/ .

Bu, http://vitalets.github.io/checklist-model/ adresinden indirilebilen yönergeyi kullanır .

Uygulamanızın bu işlevselliğe çok sık ihtiyaç duyacağı için bu yönergeye sahip olmak iyidir.

Kod aşağıdadır:

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>

JavaScript

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 iyi biçimlendirilmemiş - <div>kapanıştan daha fazla açılış etiketi var </div>. Bir şey bıraktın mı?
Peter Mortensen

0

Bebeğimi dene:

**

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();
  }
})

**

Daha sonra, onay kutularına sahip herhangi bir ng modeli için, seçtiğiniz tüm girdilerin bir dizesini döndürür:

<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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.