docs: refactor angular tutorial

pull/1633/head
mehmet-erim 6 years ago
parent ff9488f772
commit e976319f00

@ -342,12 +342,12 @@ Run `yarn start`, wait Angular to run the application and open `http://localhost
Open the `app-routing.module.ts` and replace `books` as shown below:
```typescript
import { LayoutApplicationComponent } from '@abp/ng.theme.basic';-
import { ApplicationLayoutComponent } from '@abp/ng.theme.basic';-
//...
{
path: 'books',
component: LayoutApplicationComponent,
component: ApplicationLayoutComponent,
loadChildren: () => import('./books/books.module').then(m => m.BooksModule),
data: {
routes: {
@ -357,7 +357,7 @@ import { LayoutApplicationComponent } from '@abp/ng.theme.basic';-
},
```
`LayoutApplicationComponent` configuration sets the application layout to the new page. If you would like to see your route on the navigation bar (main menu) you must also add the `data` object with `name` property in your route.
`ApplicationLayoutComponent` configuration sets the application layout to the new page. If you would like to see your route on the navigation bar (main menu) you must also add the `data` object with `name` property in your route.
![initial-books-page](images/bookstore-initial-books-page-with-layout.png)
@ -458,7 +458,7 @@ export namespace Books {
export interface Book {
name: string;
type: Type;
type: BookType;
publishDate: string;
price: number;
lastModificationTime: string;
@ -494,7 +494,7 @@ yarn ng generate service books/shared/books
![service-terminal-output](images/bookstore-service-terminal-output.png)
Modify `book.service.ts` as shown below:
Modify `books.service.ts` as shown below:
```typescript
import { Injectable } from '@angular/core';
@ -598,10 +598,9 @@ export class BookListComponent implements OnInit {
ngOnInit() {
this.loading = true;
this.store.dispatch(new GetBooks())
.subscribe(() => {
this.loading = false
};
this.store.dispatch(new GetBooks()).subscribe(() => {
this.loading = false;
});
}
}
```

@ -60,17 +60,18 @@ export class CreateUpdateBook {
}
```
<!-- Added an `id` parameter to differentiate between create or update actions -->
Open `books.state.ts` and define the `save` method that will listen to a `CreateUpdateBook` action to create a book:
```typescript
@Action(CreateUpdateBook)
save({ dispatch }: StateContext<Books.State>, { payload }: CreateUpdateBook) {
return this.booksService
.create(payload)
.pipe(switchMap(() => dispatch(new GetBooks())));
}
import { GetBooks, CreateUpdateBook } from '../actions/books.actions';
import { tap, switchMap } from 'rxjs/operators';
//...
@Action(CreateUpdateBook)
save({ dispatch }: StateContext<Books.State>, { payload }: CreateUpdateBook) {
return this.booksService
.create(payload)
.pipe(switchMap(() => dispatch(new GetBooks())));
}
```
When the `SaveBook` action dispatched, the save method is executed. It call `create` method of the `BooksService` defined before. After the service call, `BooksState` dispatches the `GetBooks` action to get books again from the server to refresh the page.
@ -301,7 +302,7 @@ Now, You can add a new book.
TODO: Description
Open the `book.service.ts` and then add the `getById` and `update` methods.
Open the `books.service.ts` and then add the `getById` and `update` methods.
```typescript
getById(id: string): Observable<Books.Book> {
@ -327,15 +328,47 @@ update(body: Books.CreateUpdateBookInput, id: string): Observable<Books.Book> {
- Added the `getById` method to get the editing book by performing an HTTP request to the related endpoint.
- Added the `update` method to update a book with the `id` by performing an HTTP request to the related endpoint.
TODO: header ??
Open the `books.actins.ts` and add `id` parameter.
```typescript
export class CreateUpdateBook {
static readonly type = '[Books] Create Update Book';
constructor(public payload: Books.CreateUpdateBookInput, public id?: string) {}
}
```
Added `id` parameter to reuse the `BooksSave` while updating and creating a book.
Open `books.state.ts` and then modify the `save` method as show below:
```typescript
@Action(CreateUpdateBook)
save({ dispatch }: StateContext<Books.State>, { payload, id }: CreateUpdateBook) {
let request;
if (id) {
request = this.booksService.update(payload, id);
} else {
request = this.booksService.create(payload);
}
return request.pipe(switchMap(() => dispatch(new GetBooks())));
}
```
### Update a Book
Inject `BooksService` dependency by adding it to the `book-list.component.ts` constructor and add variable named `selectedBook`.
```typescript
import { BooksService } from '../shared/books.service';
//...
selectedBook = {} as Books.Book;
constructor(
//...
//...
private booksService: BooksService
)
```
@ -374,19 +407,25 @@ Add the `selectedBook` definition to `onAdd` method for reuse same form while ad
```typescript
onAdd() {
this.selectedBook = {} as Books.Item;
this.selectedBook = {} as Books.Book;
//...
}
```
Add the `this.selectedBook.id` to `CreateUpdateBook` action in `save` method.
Modify the `save` method as shown below:
```typescript
save() {
//...
this.store.dispatch(new CreateUpdateBook(this.form.value, this.selectedBook.id))
//...
save() {
if (this.form.invalid) {
return;
}
this.store.dispatch(new CreateUpdateBook(this.form.value, this.selectedBook.id))
.subscribe(() => {
this.isModalOpen = false;
this.form.reset();
});
}
```
Added the `this.selectedBook.id` property to reuse the `CreateUpdateBook` action.
@ -430,7 +469,6 @@ Open the `book-list.component.html` and add modify the `p-table` as shown belo
</tr>
</ng-template>
</p-table>
>
```
Actions button added to each row of the table.
@ -445,42 +483,12 @@ Update the modal header for reuse the same modal.
```html
<ng-template #abpHeader>
<h3>{{ (selectedBook.id ? 'Edit' : 'New Book') }}</h3>
<h3>{{ selectedBook.id ? 'Edit' : 'New Book' }}</h3>
</ng-template>
```
![actions-buttons](images/bookstore-edit-modal.png)
TODO: header ??
Open the `books.actins.ts` and add `id` parameter.
```typescript
export class CreateUpdateBook {
static readonly type = '[Books] Create Update Book';
constructor(public payload: Books.CreateUpdateBookInput, public id?: string) {}
}
```
Added `id` parameter to reuse the `BooksSave` while updating and creating a book.
Open `books.state.ts` and then modify the `save` method as show below:
```typescript
@Action(CreateUpdateBook)
save({ dispatch }: StateContext<Books.State>, { payload, id }: CreateUpdateBook) {
let request;
if (id) {
request = this.booksService.update(payload, id);
} else {
request = this.booksService.create(payload);
}
return request.pipe(switchMap(() => dispatch(new GetBooks())));
}
```
TODO: description & screenshot ??
### Delete a Book
@ -512,6 +520,8 @@ export class DeleteBook {
Then, open the `books.state.ts` and add the `delete` method that will listen to a `CreateUpdateBook` action to create a book
```typescript
import { ... , DeleteBook } from '../actions/books.actions';
//...
@Action(DeleteBook)
delete({ dispatch }: StateContext<Books.State>, { id }: DeleteBook) {
return this.booksService.delete(id).pipe(switchMap(() => dispatch(new GetBooks())));
@ -553,7 +563,8 @@ constructor(
Add the following method to `BookListComponent`.
```typescript
import { ConfirmationService, Toaster } from '@abp/ng.theme.shared';
import { ... , DeleteBook } from '../../store/actions';
import { ... , Toaster } from '@abp/ng.theme.shared';
//...
delete(id: string, name: string) {
this.confirmationService
@ -571,3 +582,5 @@ The `delete` method shows confirmation popup and listens to them. When close the
The confirmation popup looks like this:
![bookstore-confirmation-popup](images/bookstore-confirmation-popup.png)
TODO: End

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Loading…
Cancel
Save