Angular 为什么复选框[checked]为所有选项多次触发
我正在创建一个具有复选框(多个选项)字段的表单。Angular 为什么复选框[checked]为所有选项多次触发,angular,angular2-forms,Angular,Angular2 Forms,我正在创建一个具有复选框(多个选项)字段的表单。 我将在我的应用程序中的许多地方使用此类字段,这就是为什么我决定使用此功能的指令 我注意到Angular2没有很好地支持复选框(多个选项)。 因此,我使用复选框的[checked]选项来验证复选框是否选中,并使用(更改)来更新我的模型 在开发过程中,我注意到在点击复选框时-[checked]会多次触发,并且会选中所有选项,而不仅仅是我点击的这个选项 我创建了一个网站来告诉你我在说什么 我想知道为什么[checked]会多次开火(在这个plunkr中
我将在我的应用程序中的许多地方使用此类字段,这就是为什么我决定使用此功能的指令 我注意到Angular2没有很好地支持复选框(多个选项)。
因此,我使用复选框的
[checked]
选项来验证复选框是否选中,并使用(更改)
来更新我的模型
在开发过程中,我注意到在点击复选框时-[checked]
会多次触发,并且会选中所有选项,而不仅仅是我点击的这个选项
我创建了一个网站来告诉你我在说什么
我想知道为什么
[checked]
会多次开火(在这个plunkr中是两次),而且它会检查所有选项,而不仅仅是单击的选项?这是角度的工作原理。更改应用程序模型的某些部分时,Angular正在检查模型所在的“区域”(更复杂,应该在Angular中搜索区域)
[checked]
每次对每个选项运行更改检测时(对于每个事件或setTimeout
或类似的异步调用),Angular2s更改检测都会调用,以确定是否需要更新项的checked
属性。我已经在angular2中创建了Multicheckbox组件。请检查Plunker Url:
请在应用程序中导入此组件,并在所有位置多次使用
1)multicheckbox.ts
import {Component, Input, Output, EventEmitter, OnInit, OnChanges, ChangeDetectionStrategy} from '@angular/core';
import {Pipe, PipeTransform} from "@angular/core";
declare var $:any;
//var chkSelectedArr=[];
/**
* Define input data interface
*/
export interface chkArrayInterface {
id: string;
title: string;
}
/**
* checked checkbox to array
*/
@Pipe({ name: 'chkChecked', pure: false })
export class ChkChecked implements PipeTransform {
transform(value, args): any {
if(args !== undefined && args.length !== 0){
if(args.includes(value)){
return true;
}else{
return false;
}
}
}
}
/**
* filter checkbox list
*/
@Pipe({ name: 'filter', pure: true })
export class FilterPipe{
transform(items: any[], args: any): any {
let filter = args.toString();
if(filter !== undefined && filter.length !== null){
if(filter.length === 0 || items.length ===0){
return items;
}else{
return filter ? items.filter(item=> item.title.toLocaleLowerCase().indexOf(filter) != -1) : items;
}
}
}
}
/**
* Multi select checkbox component
*/
@Component({
selector: 'multi-checkbox',
pipes: [FilterPipe, ChkChecked],
//changeDetection: ChangeDetectionStrategy.OnPush,
template : `
<div class="custom-multicheck-box">
<div class="input-group custom-search-box" *ngIf="isFilter">
<div class="input-group-addon">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
</div>
<input type="text" class="form-control" (keyup)="changeFilter()" (input)="txtSearch = $event.target.value" [value]="txtSearch" [placeholder]="filterTitle" />
<div class="input-group-addon" (click)="resetSearch()">
<span class="glyphicon glyphicon-remove-sign" aria-hidden="true"></span>
</div>
</div>
<div class="custom-list-box" [style.height]="height">
<input type="checkbox" [checked]="isSelectAll" (change)="selectAll($event)" />
<span class="select-all">Select All</span>
<ul>
<li *ngFor="let chk of chkArray | filter:txtSearch">
<input type="checkbox" [checked]="chk.id | chkChecked: chkSelected " (change)="selectChk($event,chk.id)" />
<span>{{chk?.title}}</span>
</li>
</ul>
</div>
</div>
`,
styles: [`
.custom-multicheck-box {
border: 1px solid rgba(0,0,0,.15);
border-radius: .25rem;
padding: 5px 0;
left: 10px;
overflow: hidden;
position: reletive
}
.custom-list-box {
margin: 10px 0px 10px 10px;
color: #0082c6;
overflow-y: auto;
}
.custom-search-box {
margin: 7px;
}
li {
padding-top: 3px;
font-weight: 400;
font-size: .8125rem;
}
li > span {
margin-left:10px;
}
span.select-all {
margin-left:10px;
font-weight: bold;
font-size: .8125rem;
}
.input-group-addon .glyphicon-remove-sign {
cursor: pointer;
}
`]
})
export class MultiCheckboxComponent implements OnInit, OnChanges {
@Input() chkArray: chkArrayInterface[]=[];
@Input() chkSelected: Array<any>=[];
@Input() filterTitle: string="Filter";
@Input() isFilter: boolean=true;
@Input() height: string="100px";
@Output() chkResult: EventEmitter<any> = new EventEmitter();
private txtSearch:string="";
private chkSelectedArr:any[]=[];
private isSelectAll:boolean;
private fiteredArr:any;
private filterPipe:any;
constructor() {
this.isSelectAllCheckbox();
}
ngOnInit() {
}
ngOnChanges(){
this.isSelectAllCheckbox();
}
/**
* Checked is selectAll or not
*/
isSelectAllCheckbox(){
if(this.chkArray !== undefined && this.chkArray !== null
&& this.chkSelected !== undefined && this.chkSelected!==null){
if(this.chkArray.length === this.chkSelected.length && this.chkArray.length !==0){
this.isSelectAll = true;
}else{
this.isSelectAll = false;
}
}
}
/**
* Select all then all checkbox selected
*/
selectAll(event) {
event.preventDefault();
this.filterPipe = new FilterPipe();
this.fiteredArr = this.filterPipe.transform(this.chkArray,this.txtSearch);
this.chkSelected = [];
this.isSelectAll = event.target.checked;
if(this.fiteredArr !== undefined && event.target.checked === true && this.fiteredArr.length !==0){
this.fiteredArr.forEach(chk => {
this.chkSelected.push(chk.id);
});
}
this.chkResult.emit({
value: this.chkSelected
})
}
/**
* Select perticular checkbox
*/
selectChk(event, val){
if(event.target.checked === true){
this.chkSelected.push(val);
}else{
var index = this.chkSelected.indexOf(val);
this.chkSelected.splice(index, 1);
}
this.isSelectAllCheckbox();
this.chkResult.emit({
value: this.chkSelected
})
}
/**
* Reset filter checkbox
*/
resetSearch(){
this.txtSearch="";
this.changeFilter();
}
/**
* Check on filter selected all or not
*/
changeFilter(){
this.filterPipe = new FilterPipe();
this.fiteredArr = this.filterPipe.transform(this.chkArray,this.txtSearch);
if(this.fiteredArr !== undefined && this.chkSelected !== undefined){
if(this.fiteredArr.length === this.chkSelected.length && this.fiteredArr.length !== 0){
this.isSelectAll = true;
}else{
this.isSelectAll = false;
}
}
}
}
import{Component,Input,Output,EventEmitter,OnInit,OnChanges,changedtectionstrategy}来自'@angular/core';
从“@angular/core”导入{Pipe,PipeTransform};
声明var$:任何;
//var chkSelectedArr=[];
/**
*定义输入数据接口
*/
导出接口chkarray接口{
id:字符串;
标题:字符串;
}
/**
*选中复选框以创建数组
*/
@管道({name:'chkChecked',pure:false})
导出类ChkChecked实现PipeTransform{
转换(值,参数):任意{
如果(args!==未定义&&args.length!==0){
if(参数包括(值)){
返回true;
}否则{
返回false;
}
}
}
}
/**
*筛选复选框列表
*/
@管道({name:'filter',pure:true})
出口级过滤管{
转换(项目:任意[],参数:任意):任意{
让filter=args.toString();
if(filter!==undefined&&filter.length!==null){
if(filter.length==0 | | items.length==0){
退货项目;
}否则{
返回筛选器?items.filter(item=>item.title.toLocaleLowerCase().indexOf(filter)!=-1):项;
}
}
}
}
/**
*多选复选框组件
*/
@组成部分({
选择器:“多复选框”,
管道:[过滤器管道,CHK检查],
//changeDetection:ChangeDetectionStrategy.OnPush,
模板:`
全选
-
{{chk?.title}
`,
风格:[`
.自定义多复选框{
边框:1px实心rgba(0,0,0,15);
边界半径:.25rem;
填充:5px0;
左:10px;
溢出:隐藏;
职位:相关职位
}
.自定义列表框{
保证金:10px 0px 10px 10px;
颜色:#0082c6;
溢出y:自动;
}
.自定义搜索框{
利润率:7px;
}
李{
垫面:3件;
字体大小:400;
字体大小:.8125rem;
}
li>span{
左边距:10px;
}
全选{
左边距:10px;
字体大小:粗体;
字体大小:.8125rem;
}
.input group加载项.glyphicon删除符号{
光标:指针;
}
`]
})
导出类MultiCheckboxComponent实现OnInit、OnChanges{
@输入()chkArray:chkArray接口[]=[];
@Input()chkSelected:Array=[];
@Input()filtertite:string=“Filter”;
@Input()isFilter:boolean=true;
@输入()高度:string=“100px”;
@Output()chkResult:EventEmitter=neweventemitter();
私有txtSearch:string=“”;
私有chkSelectedArr:any[]=[];
私有isSelectAll:布尔值;
私人Fiteredar:任何;
私人过滤管道:任何;
构造函数(){
this.isSelectalCheckbox();
}
恩戈尼尼特(){
}
ngOnChanges(){
this.isSelectalCheckbox();
}
/**
*选中是否选择全部
*/
isSelectAllCheckbox(){
如果(this.chkArray!==undefined&&this.chkArray!==null
&&this.chkSelected!==undefined&&this.chkSelected!==null){
if(this.chkArray.length==this.chkSelected.length&&this.chkArray.length!==0){
this.isSelectAll=true;
}否则{
this.isSelectAll=false;
}
}
}
/**
*选择全部,然后选中所有复选框
*/
选择全部(事件){
event.preventDefault();
this.filterPipe=新的filterPipe();
this.fiteredar=this.filterPipe.transform(this.chkArray,this.txtSearch);
this.chkSelected=[];
this.isSelectAll=event.target.checked;
if(this.fiteredar!==未定义&&event.target.checked==真&&this.fiteredar.length!==0){
this.fiteredar.forEach(chk=>{
this.chkSelected.push(chk.id);
});
}
this.chkResult.emit({
值:this.chkSelected
})
}
/**
*选中“垂直”复选框
*/
选择CHK(事件,val){
如果(event.tar)