模板中代碼:css
<span *ngFor="let tag of tags;let i=index;"> <nz-tag *ngIf="tag.visible" [nzMode]="i === -1 ? 'default' : 'closeable'" (nzAfterClose)="handleClose(tag)" (click)="showInputInArray(tag)" (nzOnClose)="onCloseTagInArray()"> <span style="font-size:1.2em;">{{ sliceTagName(tag.text) }}</span> </nz-tag> <input #inputElementInArray *ngIf="!tag.visible" type="text" nz-input nzSize='small' style="width:78px;" [(ngModel)]="tag.text" (blur)="handleInputConfirmInArray(tag)" (keydown.enter)="handleInputConfirmInArray(tag)"> </span> <nz-tag *ngIf="!inputVisible" class="editable-tag" (click)="showInput()"> <i nz-icon type="plus"></i> <span style="font-size:1.2em;">點我新增</span> </nz-tag> <input #inputElement nz-input nzSize="small" *ngIf="inputVisible" type="text" [(ngModel)]="inputValue" style="width: 78px;" (blur)="handleInputConfirm()" (keydown.enter)="handleInputConfirm()">
CSS代碼html
.editable-tag ::ng-deep .ant-tag { background: rgb(255, 255, 255); border-style: dashed; }
ts代碼typescript
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core'; import { NzMessageService } from 'ng-zorro-antd'; @Component({ selector: 'app-tag-edit', templateUrl: './tag-edit.component.html', styleUrls: ['./tag-edit.component.css'] }) export class TagEditComponent implements OnInit { private tag01:CcTag = new CcTag(); private tag02:CcTag = new CcTag(); private tag03:CcTag = new CcTag(); private tags:CcTag[] = []; private skipClick:boolean = false; private newOngoing:boolean = true; inputVisible = false; inputValue = ''; @ViewChild('inputElement') inputElement: ElementRef; @ViewChild('inputElementInArray') inputElementInArray: ElementRef; //#region 系統生命週期鉤子 constructor( private msg:NzMessageService ) { } ngOnInit() { this.initTags(); } //#endregion //#region 初始化數據 initTags(){ this.tag01.text='單袋'; this.tag01.value='單袋'; this.tag01.visible=true; this.tag02.text='雙袋'; this.tag02.value='雙袋'; this.tag02.visible=true; this.tag03.text='編織袋'; this.tag03.value='編織袋'; this.tag03.visible=true; this.tags.push(this.tag01); this.tags.push(this.tag02); this.tags.push(this.tag03); } //#endregion handleClose(removedTag: {}): void { this.tags = this.tags.filter(tag => tag !== removedTag); } sliceTagName(tag: string): string { const isLongTag = tag.length > 20; return isLongTag ? `${tag.slice(0, 20)}...` : tag; } showInput(): void { this.inputVisible = true; setTimeout(() => { this.inputElement.nativeElement.focus(); }, 10); } // 數組反應到UI上的input showInputInArray(tag:CcTag){ if(this.skipClick){ this.skipClick = false; return; } tag.visible=false; setTimeout(() => { this.inputElementInArray.nativeElement.focus(); }, 10); } handleInputConfirmInArray(tag:CcTag){ tag.visible=true; } handleInputConfirm(): void { var target:CcTag = new CcTag(); target.text=this.inputValue; target.value=this.inputValue; target.visible=true; if (this.inputValue && this.tags.indexOf(target) === -1) { this.tags.push(target); this.inputValue=''; this.showInput(); }else{ this.inputValue = ''; this.inputVisible = false; } } onCloseTagInArray(){ this.skipClick = true; } } export class CcTag{ public text:string; public value:string; public visible:boolean; }