我的目标是添加已选择的芯片。如果没有选择,则应在键入的值后加上一个筹码。
所有<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);
}
}
}
我认为主要的问题是,如果我选择一个选项,则将同时执行两个功能(selected()
和add()
)。如您所见,我已经用this.matAutocomplete.isOpen
进行过尝试,但是返回结果始终为false。
我在Stackblitz上找到了一个示例,该示例完全按照我想要的方式工作。但是我花了十多个小时来修复我的代码,以使其能够正常工作,但是我不知道我的代码到底有什么问题。
如果您有什么想法,我将不胜感激!
更新
this.currentTechnologies.push({name: value.trim()});
(在功能add()
中,仅会添加所选的选项,这很好
但是如果我键入数组technologies
中没有的其他任何内容,
不会被添加。this.currentTechnologies.push({name: this.techInput.nativeElement.value.trim()});
(在功能selected()
中),则只会添加我键入的值。答案 0 :(得分:1)
尝试删除addOnBlur选项或在文件中将其设置为false。那对我有用!