[英]Add ONLY the selected chip
我的目標是添加已選擇的芯片。 如果沒有選項,則應按已鍵入的值添加籌碼。
所有<mat-option>
值都來自我的數據庫。 我的問題是,如果我輸入一些內容並選擇了一個選項,它將添加 2 個籌碼。
例子
我的數據庫中存在值JavaScript ,它將顯示為<mat-option>
。 如果我輸入Java (也可以是J ),將選擇JavaScript 。 所以我想要的是只添加芯片JavaScript (因為它被選中)但不是兩者都添加。 這是它的樣子:
HTML
<mat-grid-tile [formGroup]="this.primaryFormGroup">
<mat-chip-list #chipList>
<mat-chip *ngFor="let currentTechnology of currentTechnologies" [selectable]="selectable"
[removable]="removable" (removed)="remove(currentTechnology)">
{{currentTechnology.name}}
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
</mat-chip>
<label>
<input #techInput
(keyup)="onKeyUp($event)"
[matAutocomplete]="auto"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="add($event)"
placeholder="Technologies"
name="technologies"
formControlName="technologies"
>
</label>
</mat-chip-list>
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" (optionSelected)="selected($event)">
<mat-option *ngFor="let data of technologies" [value]="data.technology">
<span matBadge="{{data.counter}}" matBadgeOverlap="false">{{data.technology}} </span>
</mat-option>
</mat-autocomplete>
</mat-grid-tile>
TypeScript
import {Component, ElementRef, Input, OnInit, ViewChild} from '@angular/core';
import {COMMA, ENTER, SPACE, TAB} from '@angular/cdk/keycodes';
import {MatAutocomplete, MatAutocompleteSelectedEvent, MatChipInputEvent} from '@angular/material';
import {TechnologiesService} from './technologies.service';
import {SelectionService} from '../sections/selection.service';
import {FormBuilder, FormControl, NgForm, Validators} from '@angular/forms';
import countries from '../../../assets/json/countries.json';
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.sass']
})
export class FormComponent implements OnInit {
@ViewChild('techInput', {static: false}) techInput: ElementRef<HTMLInputElement>;
@ViewChild('auto', {static: false}) matAutocomplete: MatAutocomplete;
@ViewChild('customForm', {static: true}) customForm: NgForm;
@Input() section: string;
separatorKeysCodes = [COMMA, SPACE, TAB, ENTER];
selectable = false;
removable = true;
addOnBlur = true;
technologies = [];
setTechnologies;
currentTechnologies = [];
minDate = new Date();
countries = countries;
// Primary form group
primaryFormGroup = this.fb.group({
title: '',
description: '',
gender: '',
city: '',
country: '',
language: '',
highestEducation: '',
dateOfBirth: '',
workload: '',
typeOfTask: '',
hourlyRate: '',
paymentTime: '',
minPrice: '',
maxPrice: '',
deadlineFrom: '',
deadlineUntil: '',
technologies: '',
milestones: [false, Validators.requiredTrue]
});
// Important form group
importantFormGroup = this.fb.group({
gender: [false, Validators.requiredTrue],
city: [false, Validators.requiredTrue],
country: [false, Validators.requiredTrue],
language: [false, Validators.requiredTrue],
highestEducation: [false, Validators.requiredTrue],
dateOfBirth: [false, Validators.requiredTrue],
workload: [false, Validators.requiredTrue],
hourlyRate: [false, Validators.requiredTrue],
paymentTime: [false, Validators.requiredTrue]
});
constructor(private technologiesService: TechnologiesService, private selection: SelectionService, private fb: FormBuilder) {}
// Form Control
required = new FormControl('', Validators.required);
hourlyRate = new FormControl('', Validators.max(200));
ngOnInit() {
// Set the min date
this.minDate = new Date(this.minDate.getFullYear(), this.minDate.getMonth(), this.minDate.getDate());
// Modify the form object
this.primaryFormGroup.valueChanges.subscribe(inputFields => {
if (inputFields) {
// Change technologies
if (inputFields.technologies) {
// inputFields.technologies = Array.from(this.setTechnologies);
// delete inputFields.technologies;
}
// Change type-of-task
const typeOfTask = inputFields.typeOfTask;
if (typeOfTask) {
if (typeOfTask === 'project') {
inputFields.project = 1;
} else if (typeOfTask === 'feature') {
inputFields.feature = 1;
} else if (typeOfTask === 'bugfix') {
inputFields.bugfix = 1;
} else if (typeOfTask === 'other') {
inputFields.other = 1;
}
delete inputFields.typeOfTask;
}
// Change tech
const inputEntries = Object.entries(inputFields).filter(([key, value]) => value);
// console.log('result:', inputEntries);
}
});
}
// Get the current section
getSelectedSection() {
return this.selection.getSection();
}
// On Key up, show technologies
onKeyUp(event: any): void {
if (event.target.value.trim().length > 0) {
this.technologiesService.getTechnologies(event.target.value)
.subscribe(data => {
if (JSON.stringify(this.technologies) !== JSON.stringify(data)) {
this.technologies = data;
}
});
}
}
// On enter, add technology
onEnter(evt: any) {
if (evt.source.selected) {
this.add(evt.source);
evt.source.value = '';
}
}
// Add technologies
add(event: MatChipInputEvent): void {
if (!this.matAutocomplete.isOpen) {
console.log('add');
const input = event.input;
const value = event.value;
if ((value || '').trim()) {
// E.g., { "name": "Java" }
this.currentTechnologies.push({name: value.trim()});
// Set technologies without keys
if (this.setTechnologies) {
this.setTechnologies.add(value);
} else {
this.setTechnologies = new Set();
this.setTechnologies.add(value);
}
}
// Reset the input value
if (input) {
event.input.value = '';
}
}
}
// Select the autocomplete
selected(event: MatAutocompleteSelectedEvent): void {
console.log('select');
if (!JSON.stringify(this.currentTechnologies).includes(`{"name":"${this.techInput.nativeElement.value.trim()}"`)) {
this.currentTechnologies.push({name: this.techInput.nativeElement.value.trim()});
this.techInput.nativeElement.value = '';
}
}
// Remove technology
remove(tech: any): void {
const index = this.currentTechnologies.indexOf(tech);
if (index >= 0) {
this.currentTechnologies.splice(index, 1);
}
}
}
我認為主要問題是,如果我選擇 select 一個選項,兩個函數( selected()
和add()
)都將被執行。 如您所見,我已經使用this.matAutocomplete.isOpen
進行了嘗試,但返回總是錯誤的。
我在Stackblitz上找到了一個示例,它完全按照我想要的方式工作。 但是我花了 10 多個小時來修復我的代碼以使其工作相同,但我不知道我的代碼到底有什么問題。
如果您知道它可能是什么,我將非常感激!
更新
this.currentTechnologies.push({name: value.trim()});
(在 function add()
中),只會添加選定的選項,這很好,但如果我鍵入不在我的數組technologies
中的任何其他內容,則不會添加。this.currentTechnologies.push({name: this.techInput.nativeElement.value.trim()});
(在 function selected()
中),只會添加我輸入的值。嘗試刪除 addOnBlur 選項或在 yout ts 文件中將其設置為 false。 這對我有用!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.