I'm trying to programatically set the value of Angular checkboxes to either, false
true
or indeterminate
. I understand that I cannot set the checkbox to the value indeterminate
however we do have access to [indeterminate]
on the input. Is it possible to set all three states via ngModel
somehow?
I have the following code which kinda works, however I am getting a ExpressionChangedAfterItHasBeenCheckedError
error.
HTML
<div *ngFor="let label of ClientLabels | async">
<label for="{{label.objectId}}">{{label.labelName}}</label>
<input id="{{label.objectId}}" type="checkbox" name="group" [indeterminate]="checkedLabels()"
[checked]="checkedLabels(label)" (change)="toggleSelectedLabels(label)" />
</div>
TS
checkedLabels(label): boolean {
const index = this.selectedLabels.indexOf(label.objectId);
this. indeterminateState = false;
if (!this.selectedClients.length) {
return false;
}
if (this.countInArray(this.selectedLabels, label.objectId) === this.selectedClients.length) {
return true;
}
if (index >= 0) {
this. indeterminateState = true;
}
}
countInArray(array, value) {
return array.reduce((n, x) => n + (x === value), 0);
}
Here the use case is similar to that of labels in Gmail, except clients are used in the place of an email. If all of the emails have the same label then they show as checked, however if not all of them share the label then it will show an indeterminate which can be cycled through the three states (true, false, indeterminate).
Q1. How can I cycle through these three state in the same way as you can with gmail?
Q2. Why am I getting the ExpressionChangedAfterItHasBeenCheckedError
with the current setup?
Here is a Stackblitz of current progress https://stackblitz.com/edit/angular-3bbutx
答案 0 :(得分:2)
要使复选框不确定,可以使用指令
import { Directive, ElementRef,Input } from '@angular/core';
@Directive({ selector: '[indeterminate]' })
export class IndeterminateDirective {
@Input()
set indeterminate(value)
{
this.elem.nativeElement.indeterminate=value;
}
constructor(private elem: ElementRef) {
}
}
然后您的复选框就像
<input class="pull-left" type="checkbox"
[indeterminate]="client.indeterminated"
[checked]="client.checked" (click)="click(client)"/>
其中
click(cliente: any) {
let indeterminated=(!cliente.checked && !cliente.indeterminated) ? true : false;
let checked=(!cliente.checked && cliente.indeterminated)?true:false
cliente.indeterminated = indeterminated;
cliente.checked=checked;
}
看到您有两个变量“ checked”和“ indeterminated”,可以根据需要进行循环
答案 1 :(得分:0)
是的,您可以使用 [indeterminate]="condition"
(没有任何指令)。
你不能做indeterminate="{{condition}}"
。
不同之处在于 [...]
设置元素的属性,而没有括号则设置属性。 HTMLInput 元素具有属性 indeterminate
,但没有这样的属性。
为了使用同时保持 checked
和 indeterminate
状态的 ngModel 或 FormControl,您应该在主要组件中创建自定义指令或/和其他逻辑(作为参考,请参阅 { {3}} 来自 @Eliseo)。
第一季度。我怎样才能像使用 gmail 一样循环浏览这三种状态?
处理点击,循环更改“已检查”和“不确定”对的状态。 answer。
<块引用>第 2 季度。为什么我在当前设置中收到 ExpressionChangedAfterItHasBeenCheckedError?
您在 checkedLabels
方法中有副作用,每次 Angular 检查表达式 [indeterminate]="checkedLabels()"
的值时,该方法都会更改组件的状态。
答案 2 :(得分:0)
经过长时间的搜索,我是这样做的:
在html文件中:
<input #checkboxes
type="checkbox"
[checked]="some_condition"
[indeterminate]="!some_condition && some_another_condition">
<b class="checkbox-container"></b>
并在 css 文件中:
input[type=checkbox]:checked + b:before {
content: "\2713";
font-family: ux-icons;
}
input[type=checkbox]:indeterminate + b:before {
content: "\f067";
font: 14px/1 DXIcons;
}