Você pode acessar o **código fonte** do aplicativo no [repositório GitHub](https://github.com/abpframework/abp-samples/tree/master/BookStore-Angular-MongoDb) .
-`restService.request`A função obtém parâmetros genéricos para os tipos enviados e recebidos do servidor. Este exemplo envia um `CreateUpdateBookInput`objeto e recebe um `Book`objeto (você pode definir o tipo `void`de solicitação ou retorno, se não for usado).
#### Definições de estado
Adicione a `CreateUpdateBook`ação ao `books.actions.ts`conforme mostrado abaixo:
```js
import { Books } from '../models';
export class CreateUpdateBook {
static readonly type = '[Books] Create Update Book';
Quando a `SaveBook`ação é despachada, o método save é executado. Ele chama o `create`método do `BooksService`definido anteriormente. Após a chamada de serviço, `BooksState`despacha a `GetBooks`ação para obter livros novamente do servidor para atualizar a página.
#### Adicionar um modal ao BookListComponent
Abra o `book-list.component.html`e adicione o `abp-modal`para mostrar / ocultar o modal para criar um novo livro.
`abp-modal`é um componente pré-construído para mostrar os modais. Embora você possa usar outra abordagem para mostrar um modal, `abp-modal`fornece benefícios adicionais.
Adicione um botão rotulado `New book`para mostrar o modal:
> [Os formulários reativos](https://angular.io/guide/reactive-forms) fornecem uma abordagem orientada a modelo para lidar com entradas de formulário cujos valores mudam ao longo do tempo.
Adicione uma `form`variável e injete um `FormBuilder`serviço `book-list.component.ts`como mostrado abaixo (lembre-se de adicionar a instrução de importação).
```js
import { FormGroup, FormBuilder } from '@angular/forms';
form: FormGroup;
constructor(
//...
private fb: FormBuilder
) {}
```
> O serviço [FormBuilder](https://angular.io/api/forms/FormBuilder) fornece métodos convenientes para gerar controles. Reduz a quantidade de clichê necessária para criar formulários complexos.
Adicione o `buildForm`método para criar um formulário de livro.
```js
buildForm() {
this.form = this.fb.group({
name: ['', Validators.required],
type: [null, Validators.required],
publishDate: [null, Validators.required],
price: [null, Validators.required],
});
}
```
- O `group`método de `FormBuilder`( `fb`) cria a `FormGroup`.
- Adicionado `Validators.required`método estático que valida o elemento de formulário relacionado.
Modifique o `createBook`método como mostrado abaixo:
```js
createBook() {
this.buildForm();
this.isModalOpen = true;
}
```
#### Crie os elementos DOM do formulário
Abra `book-list.component.html`e adicione o formulário no modelo de corpo do modal.
export class BookListComponent implements OnInit {
// ...
```
> O `NgbDateAdapter`valor do Datepicker converte em `Date`tipo. Consulte os [adaptadores datepicker](https://ng-bootstrap.github.io/#/components/datepicker/overview) para obter mais detalhes.
![forma de livro novo](images/bookstore-new-book-form.png)
#### Salvando o livro
Abra o `book-list.component.html`e adicione um `abp-button`para salvar o formulário.
Injectar `BooksService`dependência, adicionando-o ao `book-list.component.ts`construtor e adicione uma variável chamada `selectedBook`.
```js
import { BooksService } from '../shared/books.service';
//...
selectedBook = {} as Books.Book;
constructor(
//...
private booksService: BooksService
)
```
`booksService`é usado para obter o livro de edição para preparar o formulário. Modifique o `buildForm`método para reutilizar o mesmo formulário ao editar um livro.
Abra `book-list.component.ts`e injete o `ConfirmationService`.
```js
import { ConfirmationService } from '@abp/ng.theme.shared';
//...
constructor(
//...
private confirmationService: ConfirmationService
)
```
> `ConfirmationService` é um serviço simples fornecido pela estrutura ABP que usa internamente o PrimeNG.
Adicione um método de exclusão ao `BookListComponent`:
```js
import { ... , DeleteBook } from '../../store/actions';
import { ... , Toaster } from '@abp/ng.theme.shared';
//...
delete(id: string, name: string) {
this.confirmationService
.error(`${name} will be deleted. Do you confirm that?`, 'Are you sure?')
.subscribe(status => {
if (status === Toaster.Status.confirm) {
this.store.dispatch(new DeleteBook(id));
}
});
}
```
O `delete`método mostra um pop-up de confirmação e assina a resposta do usuário. `DeleteBook`ação despachada somente se o usuário clicar no `Yes`botão O pop-up de confirmação é exibido abaixo: