#angular #typescript #forms #angular-forms
#угловой #typescript #формы #угловые формы
Вопрос:
Я пытаюсь передать данные угловой формы во внешнюю службу, однако базовая форма возвращает нулевой объект и предотвращает любую дальнейшую обработку. Не удалось определить проблему. Я смог создать форму вставки, почти идентичную этой.
Заранее спасибо за любые предложения.
Моя форма
<div class="col-md-6">
<form #currentItem="ngForm" (ngSubmit)="updateItem(currentItem.value)" autocomplete="off" novalidate>
<div class="form-group" [ngClass]="{'error': currentItem.controls.name?.invalid amp;amp; currentItem.controls.name?.touched}">
<em *ngIf="currentItem.controls.name?.invalid amp;amp; (currentItem.controls.name?.touched)">*</em>
<label for="name">Item name:</label>
<input [formControl]="name" (ngModel)="currentItem.name" name="name" required id="name" type="text" class="form-control" placeholder="name" />
</div>
<div class="form-group" [ngClass]="{'error': currentItem.controls.description?.invalid amp;amp; currentItem.controls.description?.touched}">
<em *ngIf="currentItem.controls.description?.invalid amp;amp; (currentItem.controls.description?.touched)">*</em>
<label for="description">Item Description:</label>
<input [formControl]="description" (ngModel)="currentItem.description" name="description" required id="description" type="text" class="form-control" placeholder="description" />
</div>
<div class="form-group" [ngClass]="{'error': currentItem.controls.price?.invalid amp;amp; currentItem.controls.price?.touched}">
<em *ngIf="currentItem.controls.price?.invalid amp;amp; (currentItem.controls.price?.touched)">*</em>
<label for="price">Item Price:</label>
<input [formControl]="price" (ngModel)="currentItem.price" name="price" required id="price" type="text" class="form-control" placeholder="price" />
</div>
<div class="form-group" [ngClass]="{'error': currentItem.controls.inventory?.invalid amp;amp; currentItem.controls.inventory?.touched}">
<em *ngIf="currentItem.controls.inventory?.invalid amp;amp; (currentItem.controls.inventory?.touched)">*</em>
<label for="inventory">Item Inventory:</label>
<input [formControl]="inventory" (ngModel)="currentItem.inventory" name="inventory" required id="inventory" type="text" class="form-control" placeholder="inventory" />
</div>
<div class="form-group" [ngClass]="{'error': currentItem.controls.category?.invalid amp;amp; currentItem.controls.category?.touched}">
<em *ngIf="currentItem.controls.category?.invalid amp;amp; (currentItem.controls.category?.touched)">*</em>
<label for="category">Item Category:</label>
<input [formControl]="category" (ngModel)="currentItem.category" name="category" required id="category" type="text" class="form-control" placeholder="category" />
</div>
<div class="form-group" [ngClass]="{'error': currentItem.controls.image_url?.invalid amp;amp; currentItem.controls.image_url?.touched}">
<em *ngIf="currentItem.controls.image_url?.invalid amp;amp; currentItem.controls.image_url?.touched amp;amp; currentItem.controls.image_url?.errors.required">*</em>
<label for="image_url">Image:</label>
<input [formControl]="image_url" (ngModel)="currentItem.image_url" name="image_url" required pattern=".*/.*.(png|jpg)" id="image_url" type="text" class="form-control" placeholder="preview.png" />
<em *ngIf="currentItem.controls.image_url?.invalid amp;amp; currentItem.controls.image_url?.touched amp;amp; currentItem.controls.image_url?.errors.pattern">Must be a png or jpg url</em>
<img [src]="currentItem.controls.image_url.value" *ngIf="currentItem.controls.image_url?.valid" />
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Update</button>
<button type="button" [disabled]="currentItem.invalid" class="btn btn-default" (click)="cancel()">Cancel</button>
</div>
</form>
</div>
Компонент
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router, Params } from '@angular/router';
import { IItem } from './../../models/index';
import { ItemsService } from './../../services/index';
import { FormControl } from '@angular/forms';
import { JsonPipe } from '@angular/common';
@Component({
selector: 'app-update-item',
templateUrl: './update-item.component.html',
styleUrls: ['./update-item.component.scss']
})
export class UpdateItemComponent implements OnInit {
existingObject:any;
currentItem: IItem;
isDirty:boolean = true
// Form Controls
name = new FormControl('name');
description = new FormControl('description');
price = new FormControl('price');
inventory = new FormControl('inventory');
category = new FormControl('category');
image_url = new FormControl('image_url');
constructor(private itemsService: ItemsService, private route:ActivatedRoute, private router: Router) { }
updateItem(formValues) {
console.log(formValues); // temporary
console.log(this.currentItem); // temporary
this.itemsService.updateItem(formValues).subscribe(() => {
this.router.navigate(['/items'])
});
}
cancel() {
this.router.navigate(['/items'])
}
ngOnInit() {
this.route.params.forEach((params: Params) => {
this.itemsService.getItem( params['id']).subscribe((res: any) => {
this.existingObject = res;
this.name.setValue(this.existingObject.name);
this.description.setValue(this.existingObject.description);
this.price.setValue(this.existingObject.price);
this.inventory.setValue(this.existingObject.inventory);
this.category.setValue(this.existingObject.category);
this.image_url.setValue(this.existingObject.image_url);
})
});
}
}
Обслуживание
updateItem(item) {
let options = { headers: new HttpHeaders({'Content-Type': 'application/json'})};
return this.http.post<IItem>(this.server_url '/backend/items/update.php', item, options);
}
Ответ №1:
Вы должны поместить все свои formcontrols в FormGroup
myFormGroup: FormGroup = this.fb.group({
name: new FormControl('name'),
description: new FormControl('description'),
price: new FormControl('price'),
inventory: new FormControl('inventory'),
category: new FormControl('category'),
image_url: new FormControl('image_url'),
});
Для этого вам нужно иметь возможность создать FormGroup, таким образом, внедрить FormBuilder
зависимость.
constructor(..., private fb: FormBuilder) {}
Приведенный выше код группировки formcontrols может быть выполнен проще следующим образом:
myFormGroup: FormGroup = this.fb.group({
name: [''],
description: [''],
price: [''],
inventory: ['']),
category: [''],
image_url: [''],
});
Вам также нужно будет добавить FormGroup в свой HTML-шаблон
<form [formGroup]="myFormGroup" (ngSubmit)="updateItem()" autocomplete="off" novalidate>
...
</form>
Наконец, вы можете распечатать значения в своей функции отправки, добавив likes this
updateItem() {
if (this.myFormGroup.valid) //Not necessary since you don't use validators
console.log(this.myFormGroup.value)
}
Всю эту информацию и многое другое можно найти в документации по реактивным формам Angular