Структура и маршрутизация папок
Перед любым действием обновления нам необходимо создать файлы наших компонентов.
Итак, давайте создадим их с помощью команды Angular CLI
, которая создаст все файлы и импортирует созданный компонент OwnerUpdate
в файл owner.module.ts
:
ng g component owner/owner-update --skipTests

Нам нужно изменить файл owner.module.ts
:
RouterModule.forChild([
{ path: 'list', component: OwnerListComponent },
{ path: 'details/:id', component: OwnerDetailsComponent },
{ path: 'create', component: OwnerCreateComponent },
{ path: 'update/:id', component: OwnerUpdateComponent }
Теперь мы собираемся изменить наши файлы owner-list.component.html
и owner-list.component.ts
, чтобы включить навигацию между компонентами OwnerList и OwnerUpdate:
<button type="button" id="update" class="btn btn-success" (click)="redirectToUpdatePage(owner.id)">Update</button>
public redirectToUpdatePage = (id) => {
const updateUrl: string = `/owner/update/${id}`;
this.router.navigate([updateUrl]);
}
Обработка действия PUT в файле HTML с помощью Angular
Наш файл owner-update.component.html
будет почти таким же, как HTML-файл для создания владельца. В таком случае давайте начнем с реализации.
Во-первых, давайте добавим код оболочки в файл owner-update.component.html
:
<div class="container-fluid">
<form [formGroup]="ownerForm" autocomplete="off" novalidate (ngSubmit)="updateOwner(ownerForm.value)">
<div class="form-horizontal card card-body bg-light mb-2 mt-2">
</div>
</form>
</div>
Из предыдущего поста мы уже знаем, что formGroup
будет содержать все элементы управления внутри своего значения. Именно это значение мы отправляем в качестве параметра внутри действия updateOwner
.
Во-вторых, мы собираемся создать наши элементы управления между тегом div form-horizontal
:
<div class="form-group">
<label for="name" class="control-label col-md-2">Name of owner: </label>
<div class="col-md-5">
<input type="text" formControlName="name" id="name" class="form-control" />
</div>
<div class="col-md-5">
<em *ngIf="validateControl('name') && hasError('name', 'required')">Name is required</em>
<em *ngIf="validateControl('name') && hasError('name', 'maxlength')">Maximum allowed length is 60 characters.</em>
</div>
</div>
<div class="form-group">
<label for="dateOfBirth" class="control-label col-md-2">Date of birth: </label>
<div class="col-md-5">
<input type="text" formControlName="dateOfBirth" id="dateOfBirth" class="form-control" appDatepicker
(change)="executeDatePicker($event)" readonly />
</div>
<div class="col-md-5">
<em *ngIf="validateControl('dateOfBirth') && hasError('dateOfBirth', 'required')">Date of birth is required</em>
</div>
</div>
<div class="form-group">
<label for="address" class="control-label col-md-2">Address: </label>
<div class="col-md-5">
<input type="text" formControlName="address" id="address" class="form-control" />
</div>
<div class="col-md-5">
<em *ngIf="validateControl('address') && hasError('address', 'required')">Address is required</em>
<em *ngIf="validateControl('address') && hasError('address', 'maxlength')">Maximum allowed length is 100 characters.</em>
</div>
</div>
Каждый входной элемент содержит атрибут formControlName
, который мы собираемся использовать в файле компонента для проверки. Кроме того, функции validateControl
и hasError
- это настраиваемые функции, которые помогут нам отображать сообщения об ошибках (по-прежнему то же самое, что мы делали в компоненте CreateOwner).
Под последним тегом form-group
мы собираемся добавить код для отображения кнопок:
<br><br>
<div class="form-group">
<div class="col-md-offset-5 col-md-1">
<button type="submit" class="btn btn-info" [disabled]="!ownerForm.valid">Update</button>
</div>
<div class="col-md-1">
<button type="button" class="btn btn-danger" (click)="redirectToOwnerList()">Cancel</button>
</div>
</div>
Наконец, под тегом формы давайте добавим наши настраиваемые модальные компоненты:
<app-success-modal [modalHeaderText]="'Success message'"
[modalBodyText]="'Action completed successfully'"
[okButtonText]="'OK'"
(redirectOnOK)="redirectToOwnerList()"></app-success-modal>
<app-error-modal [modalHeaderText]="'Error message'"
[modalBodyText]="errorMessage"
[okButtonText]="'OK'"></app-error-modal>
Теперь у нас есть HTML-файл, и пора реализовать бизнес-логику для файла owner-update.component
.
Обработка действия PUT в компоненте Angular
Измените файл owner-update.component.ts
:
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { ErrorHandlerService } from './../../shared/services/error-handler.service';
import { RepositoryService } from './../../shared/services/repository.service';
import { Router, ActivatedRoute } from '@angular/router';
import { Owner } from './../../_interfaces/owner.model';
import { DatePipe } from '@angular/common';
@Component({
selector: 'app-owner-update',
templateUrl: './owner-update.component.html',
styleUrls: ['./owner-update.component.css']
})
export class OwnerUpdateComponent implements OnInit {
public errorMessage: string = '';
public owner: Owner;
public ownerForm: FormGroup;
constructor(private repository: RepositoryService, private errorHandler: ErrorHandlerService, private router: Router,
private activeRoute: ActivatedRoute, private datePipe: DatePipe) { }
}
Это базовая установка для этого компонента. Мы создаем наши свойства и внедряем все необходимые нам сервисы в этот компонент.
Давайте добавим этот код под конструктором:
ngOnInit() {
this.ownerForm = new FormGroup({
name: new FormControl('', [Validators.required, Validators.maxLength(60)]),
dateOfBirth: new FormControl('', [Validators.required]),
address: new FormControl('', [Validators.required, Validators.maxLength(100)])
});
this.getOwnerById();
}
private getOwnerById = () => {
let ownerId: string = this.activeRoute.snapshot.params['id'];
let ownerByIdUrl: string = `api/owner/${ownerId}`;
this.repository.getData(ownerByIdUrl)
.subscribe(res => {
this.owner = res as Owner;
this.ownerForm.patchValue(this.owner);
$('#dateOfBirth').val(this.datePipe.transform(this.owner.dateOfBirth, 'MM/dd/yyyy'));
},
(error) => {
this.errorHandler.handleError(error);
this.errorMessage = this.errorHandler.errorMessage;
})
}
В функции ngOnInit
мы создаем экземпляр ownerForm
со всеми элементами управления формы и добавляем правила проверки. Затем мы вызываем функцию getOwnerById
, чтобы получить с сервера владельца с точным идентификатором.
Внутри этой функции мы выполняем знакомые действия. Извлечение идентификатора из URL-адреса, отправка запроса PUT и обработка ответа, независимо от того, является ли он успешным или ошибочным.
Следует обратить внимание на преобразование значения dateOfBirth из формата с часами, минутами и секундами в формат, который мы ожидаем в нашем элементе управления вводом. С помощью функции JQuery мы помещаем это значение в поле ввода. Мы используем DatePipe для преобразования формата даты.
Давайте добавим дополнительные функции под функцией getOwnerById
:
public validateControl = (controlName: string) => {
if (this.ownerForm.controls[controlName].invalid && this.ownerForm.controls[controlName].touched)
return true;
return false;
}
public hasError = (controlName: string, errorName: string) => {
if (this.ownerForm.controls[controlName].hasError(errorName))
return true;
return false;
}
public executeDatePicker = (event) => {
this.ownerForm.patchValue({ 'dateOfBirth': event });
}
public redirectToOwnerList = () => {
this.router.navigate(['/owner/list']);
}
Это знакомые функции для проверки полей ввода, исправления значения в свойстве ownerForm и перенаправления на компонент OwnerList.
Наконец, нам нужно выполнить действие обновления, добавив код прямо под функцией redirectToOwnerList
:
public updateOwner = (ownerFormValue) => {
if (this.ownerForm.valid) {
this.executeOwnerUpdate(ownerFormValue);
}
}
private executeOwnerUpdate = (ownerFormValue) => {
this.owner.name = ownerFormValue.name;
this.owner.dateOfBirth = ownerFormValue.dateOfBirth;
this.owner.address = ownerFormValue.address;
let apiUrl = `api/owner/${this.owner.id}`;
this.repository.update(apiUrl, this.owner)
.subscribe(res => {
$('#successModal').modal();
},
(error => {
this.errorHandler.handleError(error);
this.errorMessage = this.errorHandler.errorMessage;
})
)
}
Попробуйте и сделайте несколько обновлений. Попробуйте создать успешные ответы и сообщения об ошибках с сервера, чтобы также протестировать модальные компоненты. После этого вы можете проверить, работает ли проверка формы.
Заключение
Прочитав этот пост, вы узнали:
- Как создать HTML-часть действия для обновления данных
- Способ внесения значений с сервера в группу форм Angular
- Как отправить запрос PUT на сервер
Спасибо, что прочитали этот пост, надеюсь, он был вам полезен.
В следующей статье мы собираемся написать как обработать напрос на удаление в Angular