javascript - 选择所有三态复选框时出现问题

标签 javascript angularjs checkbox

我有一个复选框列表 - 两个 parent ,每个 parent 有 5 个 child 。 parent 应该有 3 种状态(选中、未选中、不确定)。 现在,我的代码正在运行,但我正在尝试添加一个“全选”复选框, 这将选择两个 parent 及其所有 child 。

我试图做的是在上面添加一个标签:

    <label>
    <input type="checkbox" data-indeterminate-checkbox data-child- 
     list="model.people" data-property="eaten" data-ng- 
     model="model.allEaten"> All eaten
    </label>

但它不起作用 - 该复选框未按预期运行。

完整代码: http://jsfiddle.net/wnjze03h/210/

HTML:

var app = angular.module('combo', []);

app.controller('MainCtrl', ['$scope', function($scope) {
    $scope.model = {
        allEaten: false,
        people: [
            {
                name: "Bob",
                fruits: [
                    { type: 'Apple', eaten: false },
                    { type: 'Banana', eaten: false },
                    { type: 'Pear', eaten: true },
                    { type: 'Tomato', eaten: false },
                    { type: 'Grapefruit', eaten: true },
                ]
            },
            {
                name: "Joe",
                fruits: [
                    { type: 'Apple', eaten: true },
                    { type: 'Banana', eaten: true },
                    { type: 'Pear', eaten: true },
                    { type: 'Tomato', eaten: true },
                    { type: 'Grapefruit', eaten: true },
                ]
            }
        ]
    };
}]);

/**
 * Directive for an indeterminate (tri-state) checkbox.
 * Based on the examples at http://stackoverflow.com/questions/12648466/how-can-i-get-angular-js-checkboxes-with-select-unselect-all-functionality-and-i
 */
app.directive('indeterminateCheckbox', [function() {
    return {
        scope: true,
        require: '?ngModel',
        link: function(scope, element, attrs, modelCtrl) {
            var childList = attrs.childList;
            var property = attrs.property;
			
			// Bind the onChange event to update children
			element.bind('change', function() {
				scope.$apply(function () {
					var isChecked = element.prop('checked');
					
					// Set each child's selected property to the checkbox's checked property
					angular.forEach(scope.$eval(childList), function(child) {
						child[property] = isChecked;
					});
				});
			});
			
			// Watch the children for changes
			scope.$watch(childList, function(newValue) {
				var hasChecked = false;
				var hasUnchecked = false;
				
				// Loop through the children
				angular.forEach(newValue, function(child) {
					if (child[property]) {
						hasChecked = true;
					} else {
						hasUnchecked = true;
					}
				});
				
				// Determine which state to put the checkbox in
				if (hasChecked && hasUnchecked) {
					element.prop('checked', false);
					element.prop('indeterminate', true);
                    if (modelCtrl) {
                        modelCtrl.$setViewValue(false);
                    }
				} else {
					element.prop('checked', hasChecked);
					element.prop('indeterminate', false);
                    if (modelCtrl) {
					    modelCtrl.$setViewValue(hasChecked);
                    }
				}
			}, true);
		}
	};
}]);
.person {
    margin-bottom: 20px;
}

.child-list {
    margin-left: 20px;
}
    <label>
        <input type="checkbox" data-indeterminate-checkbox data-child-list="model.people.allEaten" data-property="eaten" data-ng-model="model.allEaten"> All eaten
    </label>
<div data-ng-repeat="person in model.people" class="person">
    <label>
        <input type="checkbox" data-indeterminate-checkbox data-child-list="person.fruits" data-property="eaten" data-ng-model="person.allEaten"> {{person.name}} [All eaten: {{person.allEaten}}]
    </label>
    <div data-ng-repeat="fruit in person.fruits" class="child-list">
        <label>
            <input type="checkbox" data-ng-model="fruit.eaten"> {{fruit.type}}
        </label>
    </div>
</div>

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.js"></script>

最佳答案

删除您的指令并添加以下 html

<label>
    <input style="-webkit-appearance:checkbox" type="checkbox" ng-model="model.allEaten" ng-click="selectAllEaten(model.allEaten)"> 
     allEaten {{model.allEaten}}
</label>
<div ng-repeat="person in model.people">
    <label>
        <input style="-webkit-appearance:checkbox" ng-checked="person.selected" type="checkbox" ng-model="person.selected" ng-click="selectByPerson(person)">
        {{person.name}}
    </label>
    <div ng-repeat="fruit in person.fruits" style="margin-left:20px;">
        <label>
            <input style="-webkit-appearance:checkbox" ng-checked="fruit.selected" type="checkbox" ng-model="fruit.eaten">
            {{fruit.type}}
        </label>
    </div>
</div>

在 Controller 中

$scope.selectAllEaten = function (x) {
    if (x) {
        $scope.model.people.forEach(function (item) {
            item.selected = true;
            item.fruits.forEach(function (fruit) { fruit.selected = true; });
        });
    } else {
        $scope.model.people.forEach(function (item) {
            item.selected = false;
            item.fruits.forEach(function (fruit) { fruit.selected = false; });
        });
    }
}

$scope.selectByPerson = function(x){        
    if (x.selected) {
        x.fruits.forEach(function (fruit) { fruit.selected = true; });
    }else{
        x.fruits.forEach(function (fruit) { fruit.selected = false; });
    }
}

进行进一步的验证,例如检查父级是否检查了所有子级等

关于javascript - 选择所有三态复选框时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53941644/

相关文章:

javascript - 如何访问 Select2 "change"处理程序中的 Angular 范围?

javascript - 通过javascript更改checkbox.id

javascript - 根据复选框过滤数据库

javascript - 如何更好地识别 AngularJS 中的异常来源

javascript - YUI3 - 具有相同类的链接的 Onclick 事件处理

javascript - php 页面选项卡未使用 AJAX 加载

javascript - 三个 JS - 对象移动时奇怪的光线转换行为

angularjs - Angular 更新和清除工厂变量

javascript - angular-ui-tabset:更改事件选项卡内容

每个输入的 ModelMultipleChoiceField 标签的 django 复选框表单