[Angular Schematics] 開閉可能なサイドナビ&ツールバーを3分で自動生成する

今回はAngular開発におけるComponentの自動生成手法について解説します。
アプリの基本的な画面はこの手法を用いれば、コードを書くまでもなく高速で開発できます。サービスとしての独自性の無い単純作業は極力自動化しましょう。

自動生成したナビゲーション

Angular Schematicsとは?

  • Schematicsの機能

    1. カスタマイズされたComponentをコマンドで自動生成
      • ありがちなUIは大抵これで自動生成できます
        • 今回は例として画面のサイズに応じて自動的に開閉するサイドナビとツールバーでできたナビゲーションを自動生成します
    2. モジュールの追加
    3. 設定の変更
  • 例えば、Angular CLIの以下のコマンドの処理はSchematicsで定義されています

    • ng generate
    • ng add
  • @angular/cdkと@angular/materialに含まれています

  • Angular CLIのng generateやng add といったコマンドの処理はAngular Schematicsによって定義されている

    • 自分で作ることもできます
    • 既存のSchematicsを拡張することも可能
  • 実行コマンド

    1
    ng generate @angular/material:<schematics-name> <component-name>
  • 自作可能

    • ありがちな構成を用意しておけば、サービスを高速で量産できます
    • わざわざ手順書を残すよりも遥かに効率的です

準備

Angular PJを生成

生成済みであればここはスルーしてください

    1. APの雛形を作成
      1
      ng new 'sample-ap'
      • Angular PJの初期画面はこんな感じです
        1
        ng serve --open
        image
    1. Angularの初期画面をまっさらにします
      • src/app/app.component.html をrouter-outletだけを残して削除
        1
        <router-outlet></router-outlet>

Schematicsをinstall

  • ng addコマンドで

  • npm installを使って入れると設定ファイルを弄る必要が出たりします

    1. まずはAngular Materialを入れます
      1
      ng add @angular/material
  • 出力

    • 好きなthemeを選択
      • ひとまずIndigo/Pinkにします
    • 他も基本yesでOKです
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      /firebase-sample (master) $ ng add @angular/material
      Installing packages for tooling via npm.
      Installed packages for tooling via npm.
      ? Choose a prebuilt theme name, or "custom" for a custom theme:
      ❯ Indigo/Pink [ Preview: https://material.angular.io?theme=indigo-pink ]
      Deep Purple/Amber [ Preview: https://material.angular.io?theme=deeppurple-amber ]
      Pink/Blue Grey [ Preview: https://material.angular.io?theme=pink-bluegrey ]
      Purple/Green [ Preview: https://material.angular.io?theme=purple-green ]
      Custom
      ? Set up HammerJS for gesture recognition? Yes
      ? Set up browser animations for Angular Material? Yes
      UPDATE package.json (1437 bytes)
    1. cdkをinstall
      1
      ng add @angular/cdk
  • 出力

    • packege.jsonの中身を自動で改修してくれます
      1
      2
      Skipping installation: Package already installed
      UPDATE package.json (1437 bytes)

画面表示用のComponentを生成

  • top
    1
    \src\app> ng g component top

ナビゲーションを自動生成

  • 実行

    1
    \src\app> ng g @angular/material:navigation
  • 出力

    1
    2
    3
    4
    5
    6
    $ ng generate @angular/material:navigation main-nav
    CREATE src/app/navi/navi.component.scss (193 bytes)
    CREATE src/app/navi/navi.component.html (938 bytes)
    CREATE src/app/navi/navi.component.spec.ts (1234 bytes)
    CREATE src/app/navi/navi.component.ts (583 bytes)
    UPDATE src/app/app.module.ts (1126 bytes)
  • src/appの配下にmain-navコンポーネントが自動生成されています

    1
    2
    3
    4
    5
    6
    7
    8
    src\app\main-nav> ls

    Mode LastWriteTime Length Name
    ---- ------------- ------ ----
    -a---- 2020/04/23 14:59 936 main-nav.component.html
    -a---- 2020/04/23 14:59 193 main-nav.component.scss
    -a---- 2020/04/23 14:59 1256 main-nav.component.spec.ts
    -a---- 2020/04/23 14:59 598 main-nav.component.ts

画面に反映

1. top componentに埋め込む

  • src\app\top\top.component.html
    • app-component_nameで要素を作るだけで入れ子にできます
1
<app-main-nav></app-main-nav> <!--main-naviコンポーネントを参照-->

2. topをルーティングで指定

  • 画面起動時にtopコンポーネントが表示されるように設定

  • src\app\app-routing.module.ts

    1
    2
    3
    4
    5
    6
    //routeを定めるコンポーネントをimport
    import { TopComponent } from './top/top.component';

    const routes: Routes = [
    {path: '', redirectTo: '/top', pathMatch: 'full'}, //デフォルトのパス。AP起動時
    {path: 'top', component: TopComponent }, // top画面のパスを定義

3. Localhostで画面への反映を確認

  • APを起動

    1
    ng serve --open
  • 以下のようにナビが表示されます

    • ツールバーには自動的にAngular-PJ名が入ります
自動生成したナビゲーション
  • サイドナビの表示は画面サイズに応じて変化

      • デフォルトで表示
      • デフォルトでは非表示/バーガーアイコンの押下で開閉
  • Windowを狭めてみる

  • バーガーアイコンを押下
    • Menuが表示されます
  • あとは各画面を生成してサイドナビのMenuから飛べるようにすれば、アプリの雛形ができます

  • この程度の画面はSchematicsを使って3分で実装しましょう

    • 初級者が自力で書くと、ここまででもだいぶ工数を食います

自動生成されるコードの解説

  • Schematicsで自動生成したデフォルト

  • main-nav.component.html

    • angular materialのmat-toolberやmat-sidenaviが使われています
    • WEBアプリだと毎回書きがちなパターン
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      <mat-sidenav-container class="sidenav-container">

      <!--サイドナビ-->
      <mat-sidenav #drawer class="sidenav" fixedInViewport
      [attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
      [mode]="(isHandset$ | async) ? 'over' : 'side'"
      [opened]="(isHandset$ | async) === false">
      <mat-toolbar>Menu</mat-toolbar>
      <mat-nav-list> <!--ここをrouterLink="/pass-name"で各画面に飛べるように改修-->
      <a mat-list-item href="#">Link 1</a>
      <a mat-list-item href="#">Link 2</a>
      <a mat-list-item href="#">Link 3</a>
      </mat-nav-list>
      </mat-sidenav>

      <!--ヘッダー-->
      <mat-sidenav-content>
      <mat-toolbar color="primary">
      <!--sidenavの開閉用ボタン-->
      <button
      type="button"
      aria-label="Toggle sidenav"
      mat-icon-button
      (click)="drawer.toggle()"
      *ngIf="isHandset$ | async">
      <mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
      </button>
      <span>scrab-for-aws</span>
      </mat-toolbar>
      <!-- Add Content Here -->
      </mat-sidenav-content>
      </mat-sidenav-container>
  • Tips

    • ヘッダーに複数の要素を表示して、画面サイズに応じて配置を変化させたい場合
    • 要素の間に以下を挟めばレスポンシブな余白ができます
      1
      <span style="flex:auto;"></span><!----余白-->
  • この後の作業イメージ(画面遷移の実装)

    1. 各画面用のコンポーネントを生成
      1
      ng g component <component-name>
    2. app-routing.module.tsでパスを設定
    3. main-nav.component.htmlを改修
      • 各ボタンのrouterLinkに各Componentのパスを設定

参考

@EventEmitter @Input @Output @ViewChild ACM AMP API Gateway AR AR.js AR.js Studio AWS AWS Amplify AWS Budgets AWS Cost Explorer AWS SDK for JavaScript AddThis Adobe XD Alexa Amazon CloudWatch Amazon Honycode Amazon SNS Android Angular Angular Material AngularFire AppSync Augury C CDN CI/CD Cloud Craft Cloud9 CloudFormation CloudFront CloudTrail Cognito Cost Anomaly Detection Cubase ai Cubasis LE DTM Disqus DynamoDB Elgato HD 60S Firebase Firebase Hosting Former2 Github Github Actions Github.com GithubEnterprise GithubPages Google Chrome Google Cloud Shell GraphQL Hexo Hosting IAM Ionic JSON JavaScript LadioCast Logging LowCode MFA MS Authentication MacBook Pro 16 Mind Node NETDUETTO Netflix Party Netlify Network NoCode Observable PO PdM Promise RPA ReactiveForm Recognition Route53 S3 SAM(Serverless Application Model) SAR SSL SYNCROOM Schematics ScrumInc Serverless Service Siri Sitemap Spark AR Steinberg UR44C Teams Touch Cast Studio Treetable TypeScript UI UI Bakery WAF WAFv2 WEB Page Dev WEB会議 WebAR WebSocketAPI Webhook Windows Power Automate Wireshark aot async/await aws config cloud9 display.land draw.io e2e test filter() forkJoin() google search console hexo-generator-amp iOS iPad Pro iPhone icarus map() mat input mat tree mat-checkbox mat-input mat-selection-list mmhmm ngFor plantUML popIn Aladdin2 then() vscode ”global is not defined” らくがきAR アジャイル アジャイル開発 クロスプラットフォーム ショートカット スクラム スクラム開発 テレワーク ファイル操作 ブラウザ型IDE プロダクトオーナー プロダクトマネージャー プロトタイピング リモートセッション 共同開発 双方向データバインディング 待ち合わせ処理 認定スクラムマスター 静的WEB Hosting 静的WEBサイトHosting
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×