У меня есть Реактивная форма, и я хочу загрузить изображение и два шестнадцатеричных цветных поля и отправить данные в БД. Я использую Angular Material и плагин выбора цвета, но когда я выбираю изображение или цвет и пытаюсь отправить форму, единственной зарегистрированной информацией является userId (из DataService), остальные поля формы остаются пустыми. Наоборот, если я что-то пишу вручную, у меня есть поля с полями. Это файл .ts:
customize.component.ts
import { Component, OnInit, ViewContainerRef } from '@angular/core';
import { HttpClient, HttpEventType } from '@angular/common/http';
import { slideInOutAnimation } from '../animations';
import { CustomizeApiService } from './customize-api.service';
import { FormGroup, FormControl, FormGroupDirective, NgForm, FormBuilder, Validators, AbstractControl } from '@angular/forms';
import { ErrorStateMatcher } from '@angular/material';
import { Router } from '@angular/router';
import { DataService } from '../services/data.service';
import { ColorPickerService, Cmyk } from 'ngx-color-picker';
/** Error when invalid control is dirty, touched, or submitted. */
/** TODO copy error matcher in all components */
export class MyErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
const isSubmitted = form && form.submitted;
return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted));
}
}
@Component({
selector: 'app-customize',
templateUrl: './customize.component.html',
styleUrls: ['./customize.component.css'],
// make slide in/out animation available to this component
animations: [slideInOutAnimation],
// attach the slide in/out animation to the host (root) element of this component
// tslint:disable-next-line:use-host-property-decorator
host: { '[@slideInOutAnimation]': '' }
})
export class CustomizeComponent implements OnInit {
userId = '';
selectedFile: File = null;
imageFileName = '';
url = '../../assets/images/placeholder.png';
customizeForm: FormGroup;
matcher = new MyErrorStateMatcher();
SCZ_SU_ID: '';
SCZ_LOGO_URL: '';
SCZ_MAIN_COLOR: '';
SCZ_SECONDARY_COLOR: '';
public mainColor = '#ffffff';
public secondaryColor = '#ffffff';
constructor(
private data: DataService,
private router: Router,
private http: HttpClient,
private api: CustomizeApiService,
private formBuilder: FormBuilder,
public vcRef: ViewContainerRef,
private cpService: ColorPickerService
) { }
ngOnInit() {
this.data.getUserFromToken().subscribe(utente => {
this.userId = utente['SU_ID'];
console.log(this.userId);
this.setFormValues(utente['SU_ID']);
});
this.customizeForm = this.formBuilder.group({
'SCZ_SU_ID': [null],
'SCZ_LOGO_URL': [null],
'SCZ_MAIN_COLOR': [null],
'SCZ_SECONDARY_COLOR': [null]
});
}
onFileSelected(event) {
if (event.target.files && event.target.files[0]) {
this.selectedFile = event.target.files[0];
this.imageFileName = this.selectedFile.name;
// console.log(this.selectedFile.name);
const reader = new FileReader();
reader.readAsDataURL(event.target.files[0]); // read file as data url
reader.onload = (_event) => { // called once readAsDataURL is completed
this.url = _event.target.result;
};
}
}
setFormValues(userId) {
this.customizeForm.setValue({
SCZ_SU_ID: userId,
SCZ_LOGO_URL: '',
SCZ_MAIN_COLOR: '',
SCZ_SECONDARY_COLOR: ''
});
}
onMainColorChange(mainColor: any): void {
this.mainColor = mainColor;
}
onSecondaryColorChange(secondaryColor: any): void {
this.secondaryColor = secondaryColor;
}
onFormSubmit(form: NgForm) {
console.log(form);
// this.api.postCustomization(form)
// .subscribe(res => {
// alert('file uploaded');
// this.router.navigate(['/sks']);
// }, (err) => {
// console.log(err);
// });
}
}
это HTML-файл компонента:
customize.component.html
<div class="container">
<mat-card>
<form [formGroup]="customizeForm" (ngSubmit)="onFormSubmit(customizeForm.value)">
<img mat-card-image height="200" width="200" [src]="url" alt="Photo Preview">
<div class="button-row">
<mat-form-field class="imageName">
<input matInput placeholder="Nome Immagine" formControlName="SCZ_LOGO_URL" [errorStateMatcher]="matcher" [value]="imageFileName"
(click)="imgFileInput.click()">
<mat-error>
<span *ngIf="!customizeForm.get('SCZ_LOGO_URL').valid && customizeForm.get('SCZ_LOGO_URL').touched">Scegli
un'immagine per il tuo logo</span>
</mat-error>
</mat-form-field>
<input hidden type="file" #imgFileInput (change)="onFileSelected($event)" />
</div>
<mat-form-field class="example-full-width">
<input matInput placeholder="Colore principale" [value]="mainColor" formControlName="SCZ_MAIN_COLOR" [errorStateMatcher]="matcher"
[style.background]="mainColor" [colorPicker]="mainColor" [cpPosition]="'right'" (colorPickerChange)="onMainColorChange($event)">
<mat-error>
<span *ngIf="!customizeForm.get('SCZ_MAIN_COLOR').valid && customizeForm.get('SCZ_MAIN_COLOR').touched">Scegli
il colore principale
</span>
</mat-error>
</mat-form-field>
<mat-form-field class="example-full-width">
<input matInput placeholder="Colore secondario" formControlName="SCZ_SECONDARY_COLOR" [errorStateMatcher]="matcher" [style.background]="secondaryColor"
[colorPicker]="secondaryColor" [cpPosition]="'right'" [value]="secondaryColor" (colorPickerChange)="onSecondaryColorChange($event)">
<mat-error>
<span *ngIf="!customizeForm.get('SCZ_SECONDARY_COLOR').valid && customizeForm.get('SCZ_SECONDARY_COLOR').touched">Scegli
il colore secondario</span>
</mat-error>
</mat-form-field>
<div class="button-row">
<a mat-stroked-button color="basic" [routerLink]="['/sks']" class="mat-stroked-button">
<mat-icon>keyboard_backspace</mat-icon>
</a>
<button type="submit" [disabled]="!customizeForm.valid" mat-raised-button color="primary">
<mat-icon>cloud_upload</mat-icon>
</button>
</div>
</form>
</mat-card>
</div>
для полного проекта здесь я предоставляю StackBlitz: https://stackblitz.com/github/ufollettu/SEANSA
Может ли кто-нибудь мне помочь?