Jan*_*sen 27 javascript checkbox html5 tri-state-logic angularjs
我正在寻找与这些完全相同的东西(带有"父母"的三态复选框).但是使用该解决方案并不优雅,因为我现在不依赖于jQuery,而且我需要调用$ scope.$ apply以使模型识别自动(未)检查的复选框jQuery被点击.
这是angular.js的一个错误,它要求实现ng-indeterminate-value.但这仍然不会让我与所有孩子同步,这是我认为不应该成为我的控制器的一部分.
我正在寻找的是这样的:
<input type="checkbox" ng-children-model="child.isSelected for child in listelements">.将计算布尔值列表,如果选择0,则复选框为false.如果全部选中 - >复选框为true.否则 - >复选框不确定.$scope.listelements = [{isSelected: true, desc: "Donkey"},{isSelected: false, desc: "Horse"}]<tr ng-repeat="elem in listelements"><td><input type="checkbox" ng-model="elem.isSelected"></td><td>{{elem.desc}}</td></tr>.Pir*_*ran 20
我认为您提供的示例解决方案会将太多代码放入控制器中.控制器应该只是担心列表,HTML /指令应该处理显示(包括显示全选复选框).此外,所有状态更改都是通过模型,而不是通过编写函数.
我在Plunker上整理了一个解决方案:http://plnkr.co/edit/gSeQL6XPaMsNSnlXwgHt?p = preview
现在,控制器只是设置列表:
app.controller('MainCtrl', function($scope) {
$scope.list = [{
isSelected: true,
desc: "Donkey"
}, {
isSelected: false,
desc: "Horse"
}];
});
Run Code Online (Sandbox Code Playgroud)
并且视图只是将它们渲染出来:
<div ng-repeat="elem in list">
<input type="checkbox" ng-model="elem.isSelected" /> {{elem.desc}}
</div>
Run Code Online (Sandbox Code Playgroud)
对于Select All复选框,我创建了一个名为的新指令checkbox-all:
<input checkbox-all="list.isSelected" /> Select All
Run Code Online (Sandbox Code Playgroud)
就使用而言,这就是它,希望简单......除了编写新的指令:
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);
};
});
Run Code Online (Sandbox Code Playgroud)
该parts变量打破了list.isSelected成两个部分,这样我就可以得到的值list从范围,涉及的isSelected财产中的每个对象.
我将type="checkbox"属性添加到input元素,使其成为浏览器的真正复选框.这意味着用户可以点击它,选项卡等等.
我绑定onchange事件而不是onclick,因为可以通过多种方式更改复选框,包括通过键盘.onchange事件在a内部运行,scope.$apply()以确保模型更改在最后被消化.
最后,我$watch输入模型更改复选框(最后一个true允许我观看复杂的对象).这意味着如果用户更改了复选框或出于其他原因,则"全选"复选框始终保持同步.这比编写大量的ng-click处理程序要好得多.
如果选中并取消选中复选框,则将主复选框设置为取消选中,并添加样式'greyed'(请参阅参考资料style.css).CSS样式基本上将不透明度设置为30%,导致复选框显示为灰色,但它仍然可以点击; 您还可以选中它并使用空格键更改其值.
我已经在Firefox,Chrome和Safari中进行过测试,但我没有手持IE浏览器.希望这适合你.
Mar*_*cok 20
由于您需要一种新类型/类型的组件,这听起来像是一个自定义指令的好例子.
由于父/主/三重复选框和各个双状态复选框需要相互交互,我建议使用一个带有自己的控制器的单个指令来处理逻辑.
<tri-state-checkbox checkboxes="listelements"></tri-state-checkbox>
Run Code Online (Sandbox Code Playgroud)
指示:
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
},
};
});
Run Code Online (Sandbox Code Playgroud)
更改模板以满足您的需要,或使用带有templateUrl的外部模板.
该指令假定checkboxes数组包含具有isSelected属性和desc属性的对象.
更新:如果您希望指令仅呈现三重复选框,因此各个复选框都在HTML中(如@ Piran的解决方案),这是另一个类型的plunker变体.对于这个plunker,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>
Run Code Online (Sandbox Code Playgroud)
这是皮兰解决方案的改进版本。使用.prop()而不是.attr()解决checked问题。
用法:
<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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
49791 次 |
| 最近记录: |