是否有一种简单的方法可以在网页上放置一个三态复选框并将其绑定到布尔模型,以便后者可以使用true
,false
或null
值?
我到目前为止找到的最接近的解决方案是http://jsfiddle.net/HB7LU/454/,但在设置初始视图状态时存在缺陷(因为在首次渲染期间无法获取模型值)。任何其他建议都涉及多个子复选框,并通过观察它们来解决问题。
答案 0 :(得分:8)
http://jsfiddle.net/xJhEG/我是在一个商业项目中完成的。三位是真的,假的,无效的(不是“未知的”)
.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);
});
}
};
}])
答案 1 :(得分:6)
答案 2 :(得分:3)
您利用<input type="checkbox">
的不确定状态。
的 MDN web docs 强>
存在不确定状态的复选框,其中未选中或未选中,但未确定。这是通过JavaScript使用HTMLInputElement对象的indeterminate属性设置的(不能使用HTML属性设置)。
PLUNKER: TRISTATE DIRECTIVE
<强> HTML 强>
<label>
<input type="checkbox" ng-model="state" indeterminate /> {{state}}
</label>
<强> 指令 强>
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);
});
}
}
};
});
答案 3 :(得分:1)
我已经创建了指令,您可以使用它。 Three-state checkbox AngularJS Directive on GitHub
还有一篇文章,它是如何构建的:Creating Angular 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);
}
};
}]);