sourcetip

모든 기능을 선택/선택 해제하고 값을 결정하는 angular.js 체크박스를 가져오려면 어떻게 해야 합니까?

fileupload 2023. 2. 27. 22:24
반응형

모든 기능을 선택/선택 해제하고 값을 결정하는 angular.js 체크박스를 가져오려면 어떻게 해야 합니까?

이것과 같은 을 찾고 있습니다('부모'가 있는 트라이스테이트 체크 박스).하지만 지금은 jQuery에 의존하지 않고 $scope에 전화해야 하기 때문에 이 솔루션을 사용하는 것은 우아하지 않습니다.$apply: 체크박스가 켜져 있지 않은 jQuery를 모델이 자동으로 인식하도록 합니다.

구현된 ng-indeterminate-value를 요구하는 angular.js의 버그를 다음에 나타냅니다.하지만 그래도 모든 아이들과 동기화할 수 있는 것은 아닙니다.컨트롤러의 일부가 되어서는 안 된다고 생각합니다.

제가 찾고 있는 것은 다음과 같습니다.

  • 다음과 같은 " <input type="checkbox" ng-children-model="child.isSelected for child in listelements">. ->false입니다 부언 목록이 계산되며 0이 선택된 경우 -> 체크박스가 false입니다.[ - > ]진실하다미확정
  • 이런 이 있습니다. '조종하다' 입니다.$scope.listelements = [{isSelected: true, desc: "Donkey"},{isSelected: false, desc: "Horse"}]
  • 크크 the the the the the the the the the the the the the .<tr ng-repeat="elem in listelements"><td><input type="checkbox" ng-model="elem.isSelected"></td><td>{{elem.desc}}</td></tr>.
  • 제가 알기로는 브라우저는 클릭된 undeterminate 체크박스가 어떤 상태가 되는지 판단합니다.

당신이 준 샘플 솔루션이 컨트롤러에 코드를 너무 많이 넣은 것 같아요.컨트롤러는 목록만 신경쓰고 HTML/Directives는 디스플레이를 처리합니다([Select All]체크박스 표시 포함).또한 모든 상태 변경은 쓰기 기능이 아닌 모델을 통해 이루어집니다.

Plunker에 솔루션을 정리했습니다.http://plnkr.co/edit/gSeQL6XPaMsNSnlXwgHt?p=preview

이제 컨트롤러는 목록만 설정합니다.

app.controller('MainCtrl', function($scope) {
    $scope.list = [{
        isSelected: true,
        desc: "Donkey"
    }, {
        isSelected: false,
        desc: "Horse"
    }];
});

뷰는 다음과 같이 표현합니다.

<div ng-repeat="elem in list">
  <input type="checkbox" ng-model="elem.isSelected" /> {{elem.desc}}
</div>

[ 선택(체크박스에서 [모두 선택(Select All)]라는체크박스에 대해서checkbox-all:

  <input checkbox-all="list.isSelected" /> Select All

용도는 여기까지입니다.간단하면...그 새로운 지시서를 작성하는 것 말고도:

app.directive('checkboxAll', function () {
  return function(scope, iElement, iAttrs) {
    var parts = iAttrs.checkboxAll.split('.');
    iElement.attr('type','checkbox');
    iElement.bind('change', function (evt) {
      scope.$apply(function () {
        var setValue = iElement.prop('checked');
        angular.forEach(scope.$eval(parts[0]), function (v) {
          v[parts[1]] = setValue;
        });
      });
    });
    scope.$watch(parts[0], function (newVal) {
      var hasTrue, hasFalse;
      angular.forEach(newVal, function (v) {
        if (v[parts[1]]) {
          hasTrue = true;
        } else {
          hasFalse = true;
        }
      });
      if (hasTrue && hasFalse) {
        iElement.attr('checked', false);
        iElement.addClass('greyed');
      } else {
        iElement.attr('checked', hasTrue);
        iElement.removeClass('greyed');
      }
    }, true);
  };
});

parts는 ""를 합니다.list.isSelected 그 수 있습니다.list 「」의isSelected속성을 지정합니다.

해서 ㅇㅇㅇㅇㅇㅇㅇㅇ를 붙입니다.type="checkbox"속성을 입력 요소에 적용하면 브라우저의 실제 체크박스가 됩니다.탭하거나 할 수

에 바인드 합니다.onchangeevent event than than onclick체크박스는 키보드를 사용하는 등 다양한 방법으로 변경할 수 있습니다.됩니다.scope.$apply()모델 변경 내용이 마지막에 반영되도록 합니다.

으로 저는$watch 모델(「마지막」)true을 이용하다, 로 [됩니다.[ Select All ] 。ng를 해서 클릭을 하는 .

박스가 오프가 되어 있는 는, 박스를 로 해,을 「그레이드」로 합니다( 「그레이드」를 참조해 주세요.style.css이불투명도를 30%로할 수 하여 값을 할 수도 있습니다). 이 CSS 스타일은 기본적으로 불투명도를 30%로 설정하기 때문에 체크박스는 회색으로 표시되지만 클릭할 수 있습니다.탭을 클릭하여 스페이스 바를 사용하여 값을 변경할 수도 있습니다.

Firefox, Chrome, Safari에서 테스트를 해봤는데 IE가 없습니다.이게 너한테 잘 맞았으면 좋겠어.

새로운 타입/종류의 컴포넌트를 원하기 때문에 커스텀 디렉티브에 적합한 케이스인 것 같습니다.
와 개별 parent/master/tri-state를 함께 합니다.

<tri-state-checkbox checkboxes="listelements"></tri-state-checkbox>

지시:

app.directive('triStateCheckbox', function() {
  return {
    replace: true,
    restrict: 'E',
    scope: { checkboxes: '=' },
    template: '<div><input type="checkbox" ng-model="master" ng-change="masterChange()">'
      + '<div ng-repeat="cb in checkboxes">'
      + '<input type="checkbox" ng-model="cb.isSelected" ng-change="cbChange()">{{cb.desc}}'
      + '</div>'
      + '</div>',
    controller: function($scope, $element) {
      $scope.masterChange = function() {
        if($scope.master) {
          angular.forEach($scope.checkboxes, function(cb, index){
            cb.isSelected = true;
          });
        } else {
          angular.forEach($scope.checkboxes, function(cb, index){
            cb.isSelected = false;
          });
        }
      };
      var masterCb = $element.children()[0];
      $scope.cbChange = function() {
        var allSet = true, allClear = true;
        angular.forEach($scope.checkboxes, function(cb, index){
          if(cb.isSelected) {
            allClear = false;
          } else {
            allSet = false;
          }
        });
        if(allSet)        { 
          $scope.master = true; 
          masterCb.indeterminate = false;
        }
        else if(allClear) { 
          $scope.master = false; 
          masterCb.indeterminate = false;
        }
        else { 
          $scope.master = false;
          masterCb.indeterminate = true;
        }
      };
      $scope.cbChange();  // initialize
    },
  };
});

필요에 따라 템플릿을 변경하거나 templateUrl과 함께 외부 템플릿을 사용합니다.

에 시시음음음음음음음음음음음음음 that that that that that that that that that that that that that that that that 가 포함되어 있는 오브젝트가 되어 있는 로 하고 .isSelecteddesc★★★★★★★★★★★★★★★★★★.

플런커.

업데이트: 디렉티브가 tri-state 체크박스만 렌더링하도록 하고 싶다면 개별 체크박스는 HTML(@Piran's 솔루션 등)에 있습니다. 다른 플런커 바리에이션이 있습니다.이 플런커의 경우 HTML은 다음과 같습니다.

<tri-state-checkbox checkboxes="listelements" class="select-all-cb">
</tri-state-checkbox>select all
<div ng-repeat="item in listelements">
   <input type="checkbox" ng-model="item.isSelected"> {{item.desc}}
</div>

Piran의 솔루션을 개량한 것입니다.대신 사용.attr() 고치다checkeddisclossible을 클릭합니다.

사용방법:

<div ng-repeat="elem in list">
    <input type="checkbox" ng-model="elem.isSelected" /> {{elem.desc}}
</div>
<ui-select-all items="list" prop="isSelected"></ui-select-all> Select all

디렉티브는 DOM 조작이 필요하거나 많은 DOM 조작 동작을 "재사용 가능한" 컴포넌트로 추상화하려는 경우에만 작성해야 합니다.

여기 당신이 시도했던 것과 같은 것을 실현하는 솔루션이 있습니다.그러나 이것은 컨트롤러의 논리만을 실현합니다.컨트롤러를 희박하게 유지하려면 이 모든 논리를 실행에 옮길 수 있습니다.여러 곳에서 재사용하고 싶다면 서비스를 이용하는 것도 좋습니다.

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

컨트롤러에는 DOM 조작이 없는 것에 주의해 주세요.Angular와 함께 제공되는 여러 지침을 사용하여 필요한 효과를 얻고 있습니다.새로운 지시문은 필요 없습니다.논리를 추상화하기 위해 지시를 사용해서는 안 된다고 생각합니다.

이게 도움이 됐으면 좋겠는데..

ng-model이 부울 모델(예: Y/N, '0'/'1)에 할당되어 있다고 가정할 수 없는 경우 및/또는 자신의 마크업을 가지고 싶은 경우, ngModel 기능을 활용하고 HTML 구조에 대한 가정을 하지 않는 접근법이 더 좋습니다.

예: http://plnkr.co/edit/mZQBizF72pxp4BvmNjmj?p=preview

사용 예:

  <fieldset indeterminate-group>
    <legend>Checkbox Group</legend>
    <input type="checkbox" name="c0" indeterminate-cue> Todos <br>
    <input type="checkbox" name="c1" ng-model="data.c1" ng-true-value="'Y'" ng-false-value="'F'" indeterminate-item> Item 1 <br>
    <input type="checkbox" name="c2" ng-model="data.c2" ng-true-value="'Y'" ng-false-value="'F'" indeterminate-item> Item 2 <br>
    <input type="checkbox" name="c3" ng-model="data.c3" ng-true-value="'Y'" ng-false-value="'F'" indeterminate-item> Item 3 <br>
  </fieldset>

지침(주요 부품):

angular.module('app', [])
  .directive('indeterminateGroup', function() {
    function IndeterminateGroupController() {
      this.items = [];
      this.cueElement = null;
    }
    ...
    function setAllValues(value) {
      if (this.inChangeEvent) return;

      this.inChangeEvent = true;
      try {
        this.items.forEach(function(item) {
          item.$setViewValue(value);
          item.$render();
        });
      } finally {
        this.inChangeEvent = false;
      }
    }

    return {
      restrict: "A",
      controller: IndeterminateGroupController,
      link: function(scope, element, attrs, ctrl) {
        ctrl.inputChanged = function() {
          var anyChecked = false;
          var anyUnchecked = false;
          this.items.forEach(function(item) {
            var value = item.$viewValue;
            if (value === true) {
              anyChecked = true;
            } else if (value === false) {
              anyUnchecked = true;
            }
          });

          if (this.cueElement) {
            this.cueElement.prop('indeterminate', anyChecked && anyUnchecked);
            this.cueElement.prop('checked', anyChecked && !anyUnchecked);
          }
        };
      }
    };
  })
  .directive('indeterminateCue', function() {
    return {
      restrict: "A",
      require: '^^indeterminateGroup',
      link: function(scope, element, attrs, indeterminateGroup) {
        indeterminateGroup.addCueElement(element);
        var inChangeEvent = false;
        element.on('change', function(event) {
          if (event.target.checked) {
            indeterminateGroup.checkAll();
          } else {
            indeterminateGroup.uncheckAll();
          }
        });
      }
    };
  })
  .directive('indeterminateItem', function() {
    return {
      restrict: "A",
      require: ['^^indeterminateGroup', 'ngModel'],
      link: function(scope, element, attrs, ctrls) {
        var indeterminateGroup = ctrls[0];
        var ngModel = ctrls[1];
        indeterminateGroup.addItem(ngModel);
        ngModel.$viewChangeListeners.push(function() {
          indeterminateGroup.inputChanged();
        });
      }
    };
  });

모델:

// Bring your own model

작업 내용:

  • 아이템을 삭제하다메인 디렉티브컨트롤러 내부의 $director();
  • 지시문에 더 좋은 이름을 붙인다.
  • 두 개 이상의 테이블 열에서 이 지시문을 쉽게 사용할 수 있습니다.

플런커

"use strict";

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

function Ctrl($scope) {
    var element = $("#select_all");
    $scope.$watch("$scope.isgreyed", $scope.fun = function() {
        element.prop("indeterminate", $scope.isgreyed);
    });
    $scope.list = [{
        isSelected: true,
        desc: "Donkey"
    }, {
        isSelected: false,
        desc: "Horse"
    }]
    $scope.isgreyed = true;
    $scope.master = false;
    $scope.onmasterclick = function() {
        $scope.list.map(function(v) {
            v.isSelected = $scope.master
        })
    }

    $scope.oncheckboxclick = function() {     
        if ($('.select_one:checked').length === 0) {
            $scope.isgreyed = false;
            $scope.master = false;     
        } else if ($('.select_one:not(:checked)').length === 0) {
            $scope.isgreyed = false;
            $scope.master = true;     
        } else {
            $scope.isgreyed = true;     
        }
        $scope.fun();
    }      
}

HTML:

<div ng-controller="Ctrl">
<table>
<tr>
  <td>
     <input type="checkbox" id="select_all" ng-model="master" ng-click="onmasterclick()">
  </td>
</tr>
<tr ng-repeat="elem in list">
  <td>
    <input ng-click="oncheckboxclick(elem)" class="select_one" type="checkbox" ng-model="elem.isSelected">
  </td>
  <td>{{elem.desc}}</td>
</tr>
</table>
</div>

네, 못생겼어요.

Plnker를 사용하여 리소스를 많이 소비하는 ForEach 및 기타 복잡한 내용을 사용하지 않고 보다 나은 코드로 다시 작성:

var app = angular.module('angularjs-starter', []);

app.controller('MainCtrl', function($scope) {
  $scope.listelements = [{
    isSelected: true,
    desc: "Donkey"
  }, {
    isSelected: false,
    desc: "Horse"
  }];
});

app.directive('triStateCheckbox', function() {
  return {
    replace: true,
    restrict: 'E',
    scope: {
      checkboxes: '='
    },
    template: '<input type="checkbox" ng-model="master" ng-change="masterChange()">',
    controller: function($scope, $element) {
      $scope.masterChange = function() {
        for(i=0;i<$scope.checkboxes.length; i++)
          $scope.checkboxes[i].isSelected=$scope.master;
      };
      $scope.$watch('checkboxes', function() {
        var set=0;
        for (i=0;i<$scope.checkboxes.length;i++)
          set += $scope.checkboxes[i].isSelected?1:0;
        $element.prop('indeterminate', false);
        $scope.master = (set === 0) ? false : true;
        if (set > 0 && set < i) {
          $scope.master = false;
          $element.prop('indeterminate', true);
        }
      }, true);
    }
  };
});

angular와 javascript를 조합하면 해결할 수 있을 것 같습니다.

<div>

<input type="checkbox" id="select-all" name="selectAll" value="" ng-click="checkAll($event)" />

<div >
  <input type="checkbox"  name="childCheckbox" value=""  />

  <input type="checkbox"  name="childCheckbox" value=""  />

  <input type="checkbox"  name="childCheckbox" value=""  />

  <input type="checkbox"  name="childCheckbox" value=""  />

  <input type="checkbox"  name="childCheckbox" value=""  />

  <input type="checkbox"  name="childCheckbox" value=""  />
 </div>

</div>

checkAll()에서는 다음 논리가 작업을 수행합니다.

  $scope.checkAll = function (source) {
   checkboxes = document.getElementsByName('childCheckbox');                                                 
   for (var i = 0, n = checkboxes.length; i < n; i++)   {
     checkboxes[i].checked = source.originalEvent.srcElement.checked;
   }

언급URL : https://stackoverflow.com/questions/12648466/how-can-i-get-angular-js-checkboxes-with-select-unselect-all-functionality-and-i

반응형