From 9be83bd7e14d566b97bed0c75d22207832288919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Mon, 6 Jul 2020 18:08:30 +0300 Subject: [PATCH] Completed adding new book. --- docs/en/Tutorials/Part-3.md | 236 +++++++++++++----------------------- 1 file changed, 83 insertions(+), 153 deletions(-) diff --git a/docs/en/Tutorials/Part-3.md b/docs/en/Tutorials/Part-3.md index d7df0a8568..247dc8ce18 100644 --- a/docs/en/Tutorials/Part-3.md +++ b/docs/en/Tutorials/Part-3.md @@ -738,29 +738,34 @@ Open `/src/app/book/book.component.ts` and replace the content as below: ```js import { ListService, PagedResultDto } from '@abp/ng.core'; import { Component, OnInit } from '@angular/core'; -import { BookDto, BookType } from '../models'; -import { BookService } from '../services'; -import { FormGroup, FormBuilder, Validators } from '@angular/forms'; // <== added this +import { BookDto, BookType } from './models'; +import { BookService } from './services'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; // add this @Component({ - selector: 'app-book-list', - templateUrl: './book-list.component.html', - styleUrls: ['./book-list.component.scss'], + selector: 'app-book', + templateUrl: './book.component.html', + styleUrls: ['./book.component.scss'], providers: [ListService], }) -export class BookListComponent implements OnInit { +export class BookComponent implements OnInit { book = { items: [], totalCount: 0 } as PagedResultDto; booksType = BookType; - isModalOpen = false; + form: FormGroup; // add this line + + // add bookTypes as a list of enum members + bookTypes = Object.keys(BookType).filter( + (bookType) => typeof this.booksType[bookType] === 'number' + ); - form: FormGroup; // <== added this line ==> + isModalOpen = false; constructor( public readonly list: ListService, private bookService: BookService, - private fb: FormBuilder // <== injected FormBuilder ==> + private fb: FormBuilder // inject FormBuilder ) {} ngOnInit() { @@ -772,11 +777,11 @@ export class BookListComponent implements OnInit { } createBook() { - this.buildForm(); // <== added this line + this.buildForm(); // add this line this.isModalOpen = true; } - // added buildForm method + // add buildForm method buildForm() { this.form = this.fb.group({ name: ['', Validators.required], @@ -785,23 +790,34 @@ export class BookListComponent implements OnInit { price: [null, Validators.required], }); } + + // add save method + save() { + if (this.form.invalid) { + return; + } + + this.bookService.createByInput(this.form.value).subscribe(() => { + this.isModalOpen = false; + this.form.reset(); + this.list.get(); + }); + } } ``` -* We imported `FormGroup, FormBuilder and Validators`. -* We added `form: FormGroup` variable. -* We injected `fb: FormBuilder` service to the constructor. The [FormBuilder](https://angular.io/api/forms/FormBuilder) service provides convenient methods for generating controls. It reduces the amount of boilerplate needed to build complex forms. -* We added `buildForm` method to the end of the file and executed `buildForm()` in the `createBook` method. This method creates a reactive form to be able to create a new book. - * The `group` method of `FormBuilder`, `fb` creates a `FormGroup`. - * Added `Validators.required` static method which validates the relevant form element. - -### Create the DOM elements of the form +* Imported `FormGroup`, `FormBuilder` and `Validators` from `@angular/forms`. +* Added `form: FormGroup` property. +* Add `bookTypes` as a list of `BookType` enum members. +* Injected `FormBuilder` into the constructor. [FormBuilder](https://angular.io/api/forms/FormBuilder) provides convenient methods for generating form controls. It reduces the amount of boilerplate needed to build complex forms. +* Added `buildForm` method to the end of the file and executed the `buildForm()` in the `createBook` method. +* Added `save` method. -Open `book-list.component.html` in `app\books\book-list` folder and replace ` ` with the following code part: +Open `/src/app/book/book.component.html` and replace ` ` with the following code part: ```html -
+
* @@ -835,143 +851,83 @@ Open `book-list.component.html` in `app\books\book-list` folder and replace ` ``` -- This template creates a form with `Name`, `Price`, `Type` and `Publish` date fields. -- We've used [NgBootstrap datepicker](https://ng-bootstrap.github.io/#/components/datepicker/overview) in this component. +Also replace ` ` with the following code part: + +````html + + + + + + +```` + +### Datepicker -### Datepicker requirements +We've used [NgBootstrap datepicker](https://ng-bootstrap.github.io/#/components/datepicker/overview) in this component. So, need to arrange dependencies related to this component. -Open `book.module.ts` file in `app\book` folder and replace the content as below: +Open `/src/app/book/book.module.ts` and replace the content as below: ```js import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { BookRoutingModule } from './book-routing.module'; -import { BookListComponent } from './book-list/book-list.component'; import { SharedModule } from '../shared/shared.module'; -import { NgbDatepickerModule } from '@ng-bootstrap/ng-bootstrap'; //<== added this line ==> +import { BookRoutingModule } from './book-routing.module'; +import { BookComponent } from './book.component'; +import { NgbDatepickerModule } from '@ng-bootstrap/ng-bootstrap'; // add this line @NgModule({ - declarations: [BookListComponent], + declarations: [BookComponent], imports: [ - CommonModule, BookRoutingModule, SharedModule, - NgbDatepickerModule, //<== added this line ==> - ], + NgbDatepickerModule, // add this line + ] }) -export class BookModule {} +export class BookModule { } ``` * We imported `NgbDatepickerModule` to be able to use the date picker. -Open `book-list.component.ts` file in `app\book\book-list` folder and replace the content as below: +Open `/src/app/book/book.component.ts` and replace the content as below: ```js import { ListService, PagedResultDto } from '@abp/ng.core'; import { Component, OnInit } from '@angular/core'; -import { BookDto, BookType } from '../models'; -import { BookService } from '../services'; +import { BookDto, BookType } from './models'; +import { BookService } from './services'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; -import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'; // <== added this line ==> - -@Component({ - selector: 'app-book-list', - templateUrl: './book-list.component.html', - styleUrls: ['./book-list.component.scss'], - providers: [ListService, { provide: NgbDateAdapter, useClass: NgbDateNativeAdapter }], // <== added a provide ==> -}) -export class BookListComponent implements OnInit { - book = { items: [], totalCount: 0 } as PagedResultDto; - - booksType = BookType; - - // <== added bookTypeArr array ==> - bookTypeArr = Object.keys(BookType).filter( - (bookType) => typeof this.booksType[bookType] === 'number' - ); - - isModalOpen = false; - form: FormGroup; - - constructor( - public readonly list: ListService, - private bookService: BookService, - private fb: FormBuilder - ) {} - - ngOnInit() { - const bookStreamCreator = (query) => this.bookService.getListByInput(query); - - this.list.hookToQuery(bookStreamCreator).subscribe((response) => { - this.book = response; - }); - } - - createBook() { - this.buildForm(); - this.isModalOpen = true; - } - - buildForm() { - this.form = this.fb.group({ - name: ['', Validators.required], - type: [null, Validators.required], - publishDate: [null, Validators.required], - price: [null, Validators.required], - }); - } -} -``` - -* We imported ` NgbDateNativeAdapter, NgbDateAdapter` - -* We added a new provider `NgbDateAdapter` that converts Datepicker value to `Date` type. See the [datepicker adapters](https://ng-bootstrap.github.io/#/components/datepicker/overview) for more details. - -* We added `bookTypeArr` array to be able to use it in the combobox values. The `bookTypeArr` contains the fields of the `BookType` enum. Resulting array is shown below: - - ```js - ['Adventure', 'Biography', 'Dystopia', 'Fantastic' ...] - ``` - - This array was used in the previous form template in the `ngFor` loop. - -Now, you can open your browser to see the changes: - - -![New book modal](./images/bookstore-new-book-form.png) - -### Saving the book - -Open `book-list.component.ts` file in `app\book\book-list` folder and replace the content as below: - -```js -import { ListService, PagedResultDto } from '@abp/ng.core'; -import { Component, OnInit } from '@angular/core'; -import { BookDto, BookType } from '../models'; -import { BookService } from '../services'; -import { FormGroup, FormBuilder, Validators } from '@angular/forms'; +// added this line import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'; @Component({ - selector: 'app-book-list', - templateUrl: './book-list.component.html', - styleUrls: ['./book-list.component.scss'], - providers: [ListService, { provide: NgbDateAdapter, useClass: NgbDateNativeAdapter }], + selector: 'app-book', + templateUrl: './book.component.html', + styleUrls: ['./book.component.scss'], + providers: [ + ListService, + { provide: NgbDateAdapter, useClass: NgbDateNativeAdapter } // add this line + ], }) -export class BookListComponent implements OnInit { +export class BookComponent implements OnInit { book = { items: [], totalCount: 0 } as PagedResultDto; booksType = BookType; - bookTypeArr = Object.keys(BookType).filter( + form: FormGroup; + + // <== added bookTypeArr array ==> + bookTypes = Object.keys(BookType).filter( (bookType) => typeof this.booksType[bookType] === 'number' ); isModalOpen = false; - form: FormGroup; - constructor( public readonly list: ListService, private bookService: BookService, @@ -1000,7 +956,6 @@ export class BookListComponent implements OnInit { }); } - // <== added save ==> save() { if (this.form.invalid) { return; @@ -1015,35 +970,10 @@ export class BookListComponent implements OnInit { } ``` -* We added `save` method - -Open `book-list.component.html` in `app\book\book-list` folder, find the `` element and replace this element with the following to create a new book. - -```html - - - - - - -``` - -Find the `` tag and replace below content: - -```html - -``` - - -* We added the `(ngSubmit)="save()"` to `` element to save a new book by pressing the enter. -* We added `abp-button` to the bottom area of the modal to save a new book. +* Imported ` NgbDateNativeAdapter` and `NgbDateAdapter`. +* We added a new provider `NgbDateAdapter` that converts Datepicker value to `Date` type. See the [datepicker adapters](https://ng-bootstrap.github.io/#/components/datepicker/overview) for more details. -The final modal UI looks like below: +Now, you can open your browser to see the changes: ![Save button to the modal](./images/bookstore-new-book-form-v2.png)