LoginSignup
3
5

More than 5 years have passed since last update.

Angular2 ひな型 ver.0.0.3

Last updated at Posted at 2017-03-09

Angular2 ひな型 ver.0.0.3

概要

Angular2 ひな型 ver.0.0.2 を元に以下の変更を加える。
- 認証用サービスの追加(一部ダミー)
- ログイン画面の追加(ダミー)
- プロフィール画面の追加(ダミー)
- パスワード変更画面の追加(ダミー)

手順1

  • 認証用のサービス追加
app/services/auth.service.ts
import { Injectable } from '@angular/core';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/delay';

@Injectable()
export class AuthService {
  isLoggedIn: boolean = false;

  // store the URL so we can redirect after logging in
  redirectUrl: string;

  login(email:string, password: string): Observable<boolean> {
    return Observable.of(true).delay(1000).do(val => this.isLoggedIn = true);
  }

  logout(): void {
    this.isLoggedIn = false;
  }
}

※公式サイトのサンプルほぼそのまま( loginメソッドに email、password のパラメータ追加 )

app/services/auth-guade.service.ts
import { Injectable }       from '@angular/core';
import {
  CanActivate, Router,
  ActivatedRouteSnapshot,
  RouterStateSnapshot
}                           from '@angular/router';
import { AuthService }      from './auth.service';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    let url: string = state.url;

    return this.checkLogin(url);
  }

  checkLogin(url: string): boolean {
    if (this.authService.isLoggedIn) { return true; }

    // Store the attempted URL for redirecting
    this.authService.redirectUrl = url;

    // Navigate to the login page with extras
    this.router.navigate(['/login']);
    return false;
  }
}

※公式サイトのサンプルそのまま

手順2

  • ログイン画面の追加
app/login/login-routing.ts
import { NgModule }             from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LoginComponent }       from './login.component';

const loginRoutes: Routes = [
  { path: 'login', component: LoginComponent }
];

@NgModule({
  imports: [ RouterModule.forChild(loginRoutes) ],
  exports: [ RouterModule ]
})
export class LoginRoutingModule {}
app/login/login.module.ts
import { NgModule }             from '@angular/core';
import { FormsModule }          from '@angular/forms';
import { LoginComponent }       from './login.component';
import { LoginRoutingModule }   from './login-routing.module';
import { AuthGuard }            from '../services/auth-guard.service';
import { AuthService }          from '../services/auth.service';

@NgModule({
  imports: [ LoginRoutingModule, FormsModule ],
  declarations: [ LoginComponent ],
  providers: [ AuthGuard, AuthService ]
})
export class LoginModule {}

※FormsModule、AuthGuard、AuthService の読込を行う。
※AuthGuard、AuthService は providers に追加する。

app/login/login.component.ts
import { Component,Input }  from '@angular/core';
import { Router }           from '@angular/router';
import { AuthService }      from '../services/auth.service';
import { Observable }       from 'rxjs/Observable';
import 'rxjs/add/operator/map';

@Component({
  moduleId:     module.id,
  templateUrl:  './login.component.html',
  styleUrls:    ['./login.component.css'] 
 })
export class LoginComponent {
  email: string = '';
  password: string = '';

  /**
   * 初期処理
   */
  constructor(public authService: AuthService, public router: Router) {}

  /**
   * ログイン処理
   */
  login() {

    this.authService.login(this.email, this.password).subscribe(() => {

      if (this.authService.isLoggedIn) {
        let redirect = this.authService.redirectUrl ? this.authService.redirectUrl : '/home';
        this.router.navigate([redirect]);
      } else {
        console.log('login error !!');
      }
    });
  }

  /**
   * ログアウト処理
   */
  logout() {
    this.authService.logout();
  }

  /**
   * 入力チェック処理
   */
  checkInputValue():boolean {
    var disabled = ( !this.email || !this.password );
    return disabled;
  }
}
app/login/login.component.html
<div class="panel panel-default">
  <div class="panel-heading">
    <h3 class="panel-title">ログイン</h3>
  </div>
  <div class="panel-body">
    <form class="form-signin">
      <input name="email" type="email" [(ngModel)]="email" class="form-control" placeholder="メールアドレス" required autofocus>
      <input name="password" type="password"  [(ngModel)]="password" class="form-control" placeholder="パスワード" required>
      <button class="btn btn-lg btn-primary btn-block" (click)="login()" [disabled]="checkInputValue()">
        <span class="glyphicon glyphicon-log-in" aria-hidden="true"></span> ログイン
      </button>
    </form>
  </div>
</div>
app/login/login.component.css
.panel {
  max-width: 380px;
  margin: auto;
  margin-top: 100px;
}

input {
  margin-top: 10px; 
}

button {
  margin-top: 30px; 
}

手順3

  • プロフィール画面の追加
  • パスワード変更画面の追加
app/user/user-routing.ts
import { NgModule }               from '@angular/core';
import { RouterModule, Routes }   from '@angular/router';
import { UserInfoComponent }      from './user-info.component';
import { UserPasswordComponent }  from './user-password.component';
import { AuthGuard }              from '../services/auth-guard.service';

const routes: Routes = [
  { 
    path: 'user',
    children: [
      {
        path: 'info',
        component: UserInfoComponent,
        canActivateChild: [ AuthGuard ], 
      },
      {
        path: 'password',
        component: UserPasswordComponent,
        canActivateChild: [ AuthGuard ], 
      },
    ]
  },
];

@NgModule({
  imports: [ RouterModule.forChild(routes) ],
  exports: [ RouterModule ]
})
export class UserRoutingModule { }
app/user/user.module.ts
import { NgModule }               from '@angular/core';
import { FormsModule }            from '@angular/forms';
import { UserInfoComponent }      from './user-info.component';
import { UserPasswordComponent }  from './user-password.component';
import { UserRoutingModule }      from './user-routing.module';

@NgModule({
  imports: [
    UserRoutingModule,
    FormsModule
  ],
  declarations: [
    UserInfoComponent,
    UserPasswordComponent
  ]
})
export class UserModule {}
app/user/user-info.component.ts
import { Component } from '@angular/core';

@Component({
  moduleId: module.id,
  templateUrl: 'user-info.component.html'
})
export class UserInfoComponent { }
app/user/user-info.component.html
<div class="jumbotron">
  <h2>User Info</h2>
</div>
app/user/user-password.ts
import { Component } from '@angular/core';

@Component({
  moduleId: module.id,
  templateUrl: 'user-password.component.html'
})
export class UserPasswordComponent { }
app/user/user-password.html
<div class="jumbotron">
  <h2>User Password</h2>
</div>

手順4

  • ホーム画面に認証チェック処理を追加
app/home/home-routing.ts
const routes: Routes = [
  { 
    path: 'home',
    component: HomeComponent,
    canActivate: [ AuthGuard ], 
  },
];

※ canActivate: [ AuthGuard ], を追加(これを追加することにより認証チェック処理の対象となる)

手順5

  • ナビゲーションの一部を認証済の場合のみ表示するように修正
app/app.component.html
    <div id="navbar" class="collapse navbar-collapse">
      <ul *ngIf="authService.isLoggedIn" class="nav navbar-nav">
      </ul>
      <ul *ngIf="authService.isLoggedIn" class="nav navbar-nav navbar-right">
        <li class="dropdown">

※ *ngIf="authService.isLoggedIn" を追加しログイン済の場合のみ表示するように修正

手順6

  • ログアウトの遷移先をログイン画面に変更
app/app.component.html
           <li>
              <a routerLink="/user/info">
                <span class="glyphicon glyphicon-user" aria-hidden="true"></span> プロフィール
              </a>
            </li>
            <li>
              <a routerLink="/user/password">
                <span class="glyphicon glyphicon-lock" aria-hidden="true"></span> パスワード変更
              </a>
            </li>
            <li>
              <a routerLink="/login" (click)="authService.logout()" >
                <span class="glyphicon glyphicon-log-out" aria-hidden="true"></span> ログアウト
              </a>
            </li>

※ href="#" を routerLink="/login" に修正
※ その他のプロフィール画面、パスワード変更画面への href="#" も削除

手順7

  • 追加機能・画面の読込処理を追加
app/app.module.ts
import { NgModule }               from '@angular/core';
import { BrowserModule }          from '@angular/platform-browser';
import { CommonModule }           from '@angular/common';
import { FormsModule }            from '@angular/forms';
import { Router }                 from '@angular/router';

import { AppComponent }           from './app.component';
import { AppRoutingModule }       from './app-routing.module';
import { PageNotFoundComponent }  from './not-found.component';
import { HomeModule }             from './home/home.module';
import { LoginModule }            from './login/login.module';
import { UserModule }             from './user/user.module';

@NgModule({
  imports: [ 
    BrowserModule,
    CommonModule,
    FormsModule,
    HomeModule,
    LoginModule,
    UserModule,
    AppRoutingModule
   ],
  declarations: [
    AppComponent,
    PageNotFoundComponent
  ],
  bootstrap: [
    AppComponent
  ]
})
export class AppModule {
  constructor(router: Router) {
    console.log('Routes: ', JSON.stringify(router.config, undefined, 2));
  }
}

※ LoginModule、UserModule の追加(AppRoutingModuleよりも前に)

最後に

  • 初期表示時にログイン画面が表示されることを確認
  • ログイン後にナビゲーション部にログインユーザー用のメニューが表示されることを確認
  • プロフィール画面に遷移されることを確認
  • パスワード変更画面に遷移されることを確認
  • ログアウト後にログイン画面に遷移されることを確認

参考

ver.0.0.3ソース

ver.0.0.1 解説ページ
ver.0.0.2 解説ページ

以上

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5