2014-01-25 3 views
8

웹 페이지에 단일 tri-state 확인란을 두어 부울 모델에 바인딩하는 간단한 방법이 있습니까? 그러면 후자는 true, false 또는 null 값을 취할 수 있습니까?angularjs 내에 하나의 tri-state 체크 박스를 구현하는 가장 좋은 방법은 무엇입니까?

내가 찾은 가장 가까운 해결책은 http://jsfiddle.net/HB7LU/454/이지만 초기 렌더링 상태를 설정할 때 결함이 있습니다 (첫 번째 렌더링 중에 모델 값을 가져올 방법이 없으므로). 다른 제안은 여러 자식 체크 박스를 처리하고 문제를 살펴봄으로써 문제를 해결합니다.

답변

7

http://jsfiddle.net/xJhEG/ 상업 프로젝트에서 제작했습니다. Tristates는 참, 거짓, 널 (null)

.directive('indeterminate', [function() { 
    return { 
     require: '?ngModel', 
     link: function(scope, el, attrs, ctrl) { 
     var truthy = true; 
     var falsy = false; 
     var nully = null; 
     ctrl.$formatters = []; 
     ctrl.$parsers = []; 
     ctrl.$render = function() { 
      var d = ctrl.$viewValue; 
      el.data('checked', d); 
      switch(d){ 
      case truthy: 
      el.prop('indeterminate', false); 
      el.prop('checked', true); 
      break; 
      case falsy: 
      el.prop('indeterminate', false); 
      el.prop('checked', false); 
      break; 
      default: 
      el.prop('indeterminate', true); 
      } 
     }; 
     el.bind('click', function() { 
      var d; 
      switch(el.data('checked')){ 
      case falsy: 
      d = truthy; 
      break; 
      case truthy: 
      d = nully; 
      break; 
      default: 
      d = falsy; 
      } 
      ctrl.$setViewValue(d); 
      scope.$apply(ctrl.$render); 
     }); 
     } 
    }; 
    }]) 
+0

이 브라우저가 의존을 사용할 수 있습니까? 나는 그것이 진실에서 거짓으로 바뀌는 것을 볼 수만 있었다. (지시어 나 변경 핸들러가없는 것과 같다.) IE11을 통해 테스트되었습니다. – Sebastian

+0

감사합니다.귀하의 지시어를 포크하고 두 개의 체크 박스가있는 트라이 - 스테이트 지시어를 만들었습니다. http://jsfiddle.net/laurilubi/dj6gkzrg/2/ –

6

여기 ("알 수없는"하지 않음) 내 바이올린, TruongSinh에서 시작

var truthy = true; 
var falsy = false; 
var nully = null; 
1

없이

http://jsfiddle.net/xJhEG/25/

변경 제작 한이다 지시어를 사용할 수 있습니다. Three-state checkbox AngularJS Directive on GitHub

이가 만든 방법에 관한 게시물, 또한 : Creating Angulr Directive "Three-state checkbox

당신은 DEMO

을 시도 할 수는 그리고 지시어가 다음과 같습니다

angular.module("threeStateCheckbox", []) 
    .directive("threeStateCheckbox", ['$compile', function($compile){ 
     return { 
      restrict: "A", 
      transclude: true, 
      require: 'ngModel', 
      link: function(scope, element, attrs, ngModel){ 
       var states = [true, false, null]; 
       var classNames = ["checked", "unchecked", "clear"]; 
       scope.click = function(){ 
        var st; 
        states.map(function(val, i){ 
         if(ngModel.$modelValue === val){ 
          st = states[(i+1)%3]; 
         } 
        }); 
        ngModel.$setViewValue(st); 
        ngModel.$render(); 
       }; 
       scope.tscClassName = function(){ 
        var className; 
        states.map(function(val, i){ 
         if(ngModel.$modelValue=== val){ 
          className = classNames[i]; 
         } 
        }); 
        return className; 
       }; 
       element.attr("class", "tri-sta-che "); 
       element.attr("ng-click", "click()"); 
       element.attr("ng-class", "tscClassName()"); 
       element.removeAttr("three-state-checkbox"); 
       $compile(element)(scope); 
      } 
     }; 
    }]); 
1

당신을 활용할 수있다 불확정 상태는 <input type="checkbox">입니다.

MDN web docs :가 존재합니다. 확인란이 선택되지 않았거나 선택되지 않았지만 결정되지 않은 확인란이 있습니다. 이것은 JavaScript를 통해 HTMLInputElement 객체의 불확정 속성을 사용하여 설정됩니다 (HTML 속성을 사용하여 설정할 수 없음).

PLUNKER : TRISTATE DIRECTIVE

HTML

<label> 
    <input type="checkbox" ng-model="state" indeterminate /> {{state}} 
</label> 

DIRECTIVE

app.directive('indeterminate', function() { 
    return { 
    restrict: 'A', 
    scope: { 
     model: '=ngModel' 
    }, 
    link: function(scope, el, attrs, ctrl) { 
     var states = [true, false, undefined]; 
     var index = states.indexOf(scope.model); 
     setIndeterminate(); 

     el.bind('click', function() { 
     scope.model = states[++index % 3]; 
     setIndeterminate(); 
     }); 

     function setIndeterminate() { 
     scope.$applyAsync(function() { 
      el[0].indeterminate = (scope.model === undefined); 
     }); 
     } 
    } 
    }; 
}); 

EXTRA를 : 당신이 불확실한 상태를 나타내는 문자열을 추가하려면는이 CSS

input:indeterminate:after { 
    content: "indeterminate"; 
    padding-left: 20px; 
    display: inline-block; 
    width: 80px; 
}