[ตอนที่ 4] Social App Workshop ด้วย ASP.NET Core 3 กับ Angular 9 ระบบ Login และ Register

Line
Facebook
Twitter
Google

สารบัญเนื้อหา

  1. สร้าง Login Form
  2. ปรับปรุง Login Form โดยใช้ Angular Template Forms
  3. สร้าง Angular Services (login)
  4. ใช้งาน Angular Services (login)
  5. ใช้งาน *ngIf เพื่อแสดง HTML ตามเงื่อนไข
  6. สร้างระบบการลงทะเบียนสำหรับ User
  7. การส่งข้อมูลเป็น Input จาก Parent ไปยัง Child
  8. การส่งข้อมูลเป็น Output จาก Child ไปยัง Parent
  9. สร้างและใช้งาน Register Service เพื่อลงทะเบียน User

1. สร้าง Login Form

สร้าง Login Form โดยใช้ Bootstrap ซึ่งในที่นี้เราจะสร้าง Nav Component เพื่อใส่ From Login เข้าไปในส่วนบนของ Page

เราจะใช้เทมเพลตตามลิ้งก์นี้ https://getbootstrap.com/docs/4.5/examples/sign-in/

ทำการสร้าง Login Component ใน Angular App และวางเทมเพลต HTML ลงไปใน login.component.html

<div class="text-center">
  <form class="form-signin">
    <img class="mb-4" src="https://getbootstrap.com/docs/4.5/assets/brand/bootstrap-solid.svg" alt="" width="72" height="72">
    <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
    <label for="inputUsername" class="sr-only">Username</label>
    <input type="text" id="inputUsername" class="form-control" placeholder="Username" required="" autofocus="">
    <label for="inputPassword" class="sr-only">Password</label>
    <input type="password" id="inputPassword" class="form-control" placeholder="Password" required="">
    <div class="checkbox mb-3">
      <label>
        <input type="checkbox" value="remember-me"> Remember me
      </label>
    </div>
    <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
    <p class="mt-5 mb-3 text-muted">© 2017-2020 Social App</p>
  </form>
</div>

เพิ่ม CSS ใน Styles.css ดังนี้

.form-signin {
    width: 100%;
    max-width: 330px;
    padding: 15px;
    margin: auto;
}

เพิ่ม <app-login></app-login> ใน app.component.html

ทดสอบรัน

2. ปรับปรุง Login Form โดยใช้ Angular Template Forms

สร้างฟังก์ชันเมื่อกด Submit จาก Login Form ใน login.component.ts ดังนี้

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
  model: any = {};

  constructor() { }

  ngOnInit() {
  }

  login() {
    console.log(this.model);
  }

}

เพิ่ม FormsModule ใน imports ของ app.module.ts

import { FormsModule } from '@angular/forms';

ปรับปรุงโค้ดใน login.component.html ให้ทำงานร่วมกับ Angular Template Form

<div class="text-center">
  <form #loginForm="ngForm" class="form-signin" (ngSubmit)="login()">
    <img class="mb-4" src="https://getbootstrap.com/docs/4.5/assets/brand/bootstrap-solid.svg" alt="" width="72" height="72">
    <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
    <label for="inputUsername" class="sr-only">Username</label>
    <input type="text" id="inputUsername" name="inputUsername" class="form-control" placeholder="Username" required autofocus="" [(ngModel)]="model.username">
    <label for="inputPassword" class="sr-only">Password</label>
    <input type="password" id="inputPassword" name="inputPassword" class="form-control" placeholder="Password" required [(ngModel)]="model.password">
    <div class="checkbox mb-3">
      <label>
        <input type="checkbox" value="remember-me"> Remember me
      </label>
    </div>
    <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
    <p class="mt-5 mb-3 text-muted">© 2017-2020 Social App</p>
  </form>
</div>

ทดสอบรัน และสังเกตุค่าที่ส่งผ่านเข้ามาทาง Console

เพิ่ม [disabled]=”!loginForm.valid” ในปุ่ม Submit เพื่อป้องกันไม่ให้กดถ้ากรอกข้อมูลยังไม่ครบ

3. สร้าง Angular Services (login)

สร้างโฟลเดอร์ _services ภายใต้ app และสร้าง auth service โดยใช้คำสั่ง Generate Service

เพิ่ม Service Providers ใน Providers ของ app.module.ts

สร้าง Service Logn ใน auth.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  baseUrl = 'http://localhost:5000/api/auth/';

  constructor(private http: HttpClient) { }

  login(model: any) {
    return this.http.post(this.baseUrl + 'login', model).pipe(
      map((response: any) => {
        const user = response;
        if (user) {
          localStorage.setItem('token', user.token);
        }
      })
    );
  }

}

4. ใช้งาน Angular Services (login)

ปรับปรุงโค้ดใน login.component.ts เพื่อเรียกใช้งาน Auth Service

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../_services/auth.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
  model: any = {};

  constructor(private authService: AuthService) { }

  ngOnInit() {
  }

  login() {
    this.authService.login(this.model).subscribe(next => {
      console.log('Loged in successfully');
    }, error => {
      console.log('Failed to login');
    });
  }

}

ทดลองรัน และทำการ Login

และถ้า Login สำเร็จ token จะถูกเก็บไว้ที่ Local Storage

5. ใช้งาน *ngIf เพื่อแสดง HTML ตามเงื่อนไข

เพิ่ม nav component เพื่อแสดงเมนูด้านบนของ Social App และเขียนโค้ด html ใน nav.component.html

<nav class="navbar navbar-expand-md navbar-dark bg-dark">
  <a class="navbar-brand" href="#">Social App</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarsExampleDefault">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Lists</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Messages</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Register</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Logout</a>
      </li>
    </ul>

    <div class="dropdown">
      <a class="dropdown-toggle text-light">
        Welcome User
      </a>

      <div class="dropdown-menu">
        <a href="#" class="dropdown-item"><i class="fa fa-user"></i> Edit Profile</a>
        <div class="dropdown-divider"></div>
        <a href="#" class="dropdown-item"><i class="fa fa-sign-out"></i> Logout</a>
      </div>
    </div>

  </div>
</nav>

และเพิ่ม <app-nav></app-nav> ที่บนสุดของ app.component.html จะได้หน้าตาของ Social App ดังนี้

เขียนฟังก์ชันตรวจสอบสถานะการ login ใน nav.component.ts

loggedIn() {
    const token = localStorage.getItem('token');
    return !!token;
}

เขียนโค้ดสำหรับการ Logout ใน nav.component.ts

logout() {
    localStorage.removeItem('token');
    console.log('Logged out');
}

ในส่วนของ html ของ nav ใส่ *ngIf=”loggedIn()” หากต้องการให้ส่วนนั้นแสดงเมื่อทำการ login สำเร็จแล้ว และใส่ *ngIf=”!loggedIn()” หากต้องการให้ส่วนนั้นแสดงเมื่อยังไม่ login

<nav class="navbar navbar-expand-md navbar-dark bg-dark">
  <a class="navbar-brand" href="#">Social App</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarsExampleDefault">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Lists</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Messages</a>
      </li>
      <li *ngIf="!loggedIn()" class="nav-item">
        <a class="nav-link" href="#">Register</a>
      </li>
      <li *ngIf="loggedIn()" class="nav-item">
        <a class="nav-link" (click)="logout()">Logout</a>
      </li>
    </ul>

    <div *ngIf="loggedIn()" class="dropdown">
      <a class="dropdown-toggle text-light">
        Welcome User
      </a>

      <div class="dropdown-menu">
        <a href="#" class="dropdown-item"><i class="fa fa-user"></i> Edit Profile</a>
        <div class="dropdown-divider"></div>
        <a href="#" class="dropdown-item"><i class="fa fa-sign-out"></i> Logout</a>
      </div>
    </div>

  </div>
</nav>

ทดสอบการทำงานเมื่อ login และไม่ login

ย้ายฟังก์ชันตรวจสอบสถานะการ login และฟังชันการ logout ใน nav.component.ts ไปไว้ใน auth.service.ts

ปรับปรุงโค้ดใน nav.component.ts ไปเรียก service แทน

เพิ่มการเรียกฟังก์ชันตรวจสอบการ login ใน login.component.ts

เพิ่ม *ngIf=”!loggedIn()” ใน login.component.html

ทดสอบการแสดงผลเมื่อ login และไม่ login อีกครั้ง

6. สร้างระบบการลงทะเบียนสำหรับ User

สร้าง home component และ register component โดยมี code ดังนี้

register.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-register',
  templateUrl: './register.component.html',
  styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
  model: any = {};

  constructor() { }

  ngOnInit() {
  }
  
  register() {
    console.log(this.model);
  }

  cancel() {
    console.log('Cancelled');
  }
}

register.component.html

<form #registerForm="ngForm" (ngSubmit)="register()">
  <h2 class="text-center text-primary mt-2">Sign Up</h2>
  <hr>

  <div class="form-group">
    <input type="text" class="form-control" required name="username" [(ngModel)]="model.username" placeholder="Username">
  </div>

  <div class="form-group">
    <input type="password" class="form-control" required name="password" [(ngModel)]="model.password" placeholder="Password">
  </div>

  <div class="form-group text-center">
    <button class="btn btn-success" type="submit">Register</button>
    <button class="btn btn-default" type="button" (click)="cancel()">Cancel</button>
  </div>

</form>

home.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
  registerMode = false;

  constructor() { }

  ngOnInit() {
  }

  registerToggle() {
    this.registerMode = !this.registerMode;
  }

}

home.component.html

<div class="container mt-5">
  <div *ngIf="!registerMode" class="text-center">
    <h1>Find your network</h1>
    <p class="lead">Come on in to view your network... All you need to do is sign up!</p>
    <div class="text-center">
      <button class="btn btn-primary btn-lg mr-2" (click)="registerToggle()">Register</button>
      <button class="btn btn-info btn-lg">Learn more</button>
    </div>
  </div>

  <div *ngIf="registerMode" class="container">
    <div class="row justify-content-center">
      <div class="col-4">
        <app-register></app-register>
      </div>
    </div>
  </div>
</div>

ทดสอบรัน และดูผลการแสดงผล และ Console

7. การส่งข้อมูลเป็น Input จาก Parent ไปยัง Child

ตอนนี้ Home กับ Register มีความสัมพันธ์กัน โดย Home เป็น Parent ของ Register และ Register เป็น Child ของ Home

เราจะทำการส่งข้อมูลเป็น Input จาก Home ไปยัง Register ซึ่งเป็นการส่งข้อมูลจาก Parent ไปยัง Child

ทำการ [AllowAnonymous] ใน API เพื่อให้สามารถเรียกข้อมูลได้ก่อน

ย้ายการทำงานเรียกข้อมูลจาก Value Component ไปที่ Home Component แล้วลบ Value Component ทิ้งไป

เพิ่ม Input ใน register.component.ts

ส่งค่า Input จาก Parent Home

แสดงค่า Input Value ที่ได้รับบน Register

ลบการแสดงผล Value และส่วนที่เกี่ยวข้องออกทั้งหมด จะได้ไม่มีผลต่อหน้าจอ ก่อนไปหัวข้อถัดไป

8. การส่งข้อมูลเป็น Output จาก Child ไปยัง Parent

เราจะทำการส่งข้อมูลเป็น Output จาก Register ไปยัง Home ซึ่งเป็นการส่งข้อมูลจาก Child ไปยัง Parent

เพิ่ม Output ข้อมูลที่ต้องการส่งใน register.component.ts

สร้างฟังก์ชั่นเพื่อรับค่า Output จาก register ใน home.component.ts

เชื่อมโยงการส่งข้อมูลจาก register

ทดสอบรัน จะพบว่าสามารถกด Cancel Register เพื่อเปลี่ยนการแสดงผลได้แล้ว

9. สร้างและใช้งาน Register Service เพื่อลงทะเบียน User

สร้าง Register Service ใน auth.service.ts

เรียกใช้งาน Register Service จาก register.component.ts

โปรดติดตามตอนต่อไป…

Line
Facebook
Twitter
Google
การติดตั้งและใช้งาน Datatables ร่วมกับ Angular
[ตอนที่ 16] Social App Workshop ด้วย ASP.NET Core 3 กับ Angular 9 การทำ Sorting
[ตอนที่ 15] Social App Workshop ด้วย ASP.NET Core 3 กับ Angular 9 การทำ Filtering
[ตอนที่ 14] Social App Workshop ด้วย ASP.NET Core 3 กับ Angular 9 การใช้งาน Paging
เตรียม Atom สำหรับ React Native #3
เตรียม Visual Studio Code สำหรับ React Native #2
การติดตั้ง React Native บน macOs #1
การกำหนดค่า TF_MIN_GPU_MULTIPROCESSOR_COUNT เพื่อให้ TensorFlow ใช้งาน GPU ทุกตัว
ติดตั้ง Ubuntu 17.04 ใช้งานร่วมกับ Windows 10
การติดตั้ง TensorFlow & Caffe บน Ubuntu 16.04