Fusic Tech Blog

Fusicエンジニアによる技術ブログ

Nebular で作るAngularアプリ
2024/03/25

Nebular で作るAngularアプリ

Nebular とは

Angular アプリを作るためのツール群で公式サイトでも言っているようにただの UI ツールキットを提供しているだけではなく、認証機構やセキュリティもカバーしてくれています。

UI コンポーネントも変わったものが多く、チャット画面の雛形 Chat UIを用意してくれていたりとかなり便利なものが揃っています。

今回はその UI コンポーネントを使って簡単なアプリを作りたいと思います。

どんなものができたかはデモがあるので、以下から確認できます。

https://goofy-swanson-b0b82b.netlify.com/

これは Nebular のFlip Card を使って実現しています。

Angular プロジェクト作成

$ ng new my-nebular-app

Nebular 導入

$ npm install @nebular/theme @angular/cdk @angular/animations

$ npm install @nebular/bootstrap bootstrap nebular-icons

モジュールを追加します。

// app.module.ts



import { BrowserModule } from '@angular/platform-browser';

import { NgModule } from '@angular/core';



import { AppComponent } from './app.component';



// import nebular theme module

import { NbThemeModule } from '@nebular/theme';





@NgModule({

  declarations: [

    AppComponent

  ],

  imports: [

    BrowserModule,

    // this will enable the default theme, you can change this by passing `{ name: 'cosmic' }` to enable the dark theme

    NbThemeModule.forRoot()

  ],

  providers: [],

  bootstrap: [AppComponent]

})

export class AppModule { }

スタイルを追加します。

{
    ...
    "styles": [
      "src/styles.css",
      "node_modules/@nebular/theme/styles/prebuilt/default.css", // or cosmic.css
      "node_modules/bootstrap/dist/css/bootstrap.css", // bootstrap styles
      "node_modules/@nebular/bootstrap/styles/prebuilt/default.css",
      "node_modules/nebular-icons/scss/nebular-icons.scss"
    ],
    ...
}

Router とフラッシュカード表示 Component を生成します。

$ ng generate module app-routing --flat --module=app
$ ng generate component FlashCards
// app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { FlashCardsComponent } from './flash-cards/flash-cards.component';

const routes: Routes = [
  { path: '', component: FlashCardsComponent }
];

@NgModule({
  imports: [ RouterModule.forRoot(routes) ],
  exports: [ RouterModule ]
})
export class AppRoutingModule { }
// app.module.ts
...
import { NbLayoutModule, NbThemeModule } from '@nebular/theme';
import { FlashCardsComponent } from './flash-cards/flash-cards.component';

@NgModule({
  declarations: [
    AppComponent,
    FlashCardsComponent
  ],
  imports: [
      ...
      NbLayoutModule
  ],
  ...
})
export class AppModule { }
// app.component.html

<nb-layout>
  <nb-layout-header fixed>Flash Card App</nb-layout-header>
  <nb-layout-column>
    <router-outlet></router-outlet>
  </nb-layout-column>
</nb-layout>

フラッシュカードページ

Class を作成します。

$ ng generate class FlashCardItem
// flash-card-item.ts
export class FlashCardItem {
  constructor(
    public id: number,
    public front: string,
    public back: string
  ) { }
}

フラッシュカードを作成/表示する画面コンポーネントを作成します。

// flash-cards.component.ts
import { Component, OnInit } from '@angular/core';
import { FlashCardItem } from '../flash-card-item';

@Component({
  selector: 'app-flash-cards',
  templateUrl: './flash-cards.component.html',
  styleUrls: ['./flash-cards.component.css']
})
export class FlashCardsComponent implements OnInit {
  items: Array<FlashCardItem>;
  frontText: string;
  backText: string;
  constructor() {
    this.items = [
      new FlashCardItem(1, 'Front1', 'Back1' ),
      new FlashCardItem(2, 'Front2', 'Back2' ),
      new FlashCardItem(3, 'Front3', 'Back3' )
    ];
    this.frontText = '';
    this.backText = '';
  }

  ngOnInit() {}

  onClickSave() {
    this.items.push(new FlashCardItem(this.items.length + 1, this.frontText, this.backText));
  }
}
<!-- flash-cards.component.html -->
<div>
  <div class="row">
    <nb-card class="w-100 m-3">
      <nb-card-body class="text-center">
        <input type="text" class="mb-3" nbInput fullWidth status="info" placeholder="Front" [(ngModel)]="frontText">
        <input type="text" class="mb-3" nbInput fullWidth status="danger" placeholder="Back" [(ngModel)]="backText">
        <button nbButton hero status="primary" class="w-50" (click)="onClickSave()">Save</button>
      </nb-card-body>
    </nb-card>
  </div>
  <div class="row" *ngFor="let item of items">
    <div class="col">
      <nb-flip-card>
        <nb-card-front>
          <nb-card accent="danger">
            <nb-card-body>
              {{ item.front }}
            </nb-card-body>
          </nb-card>
        </nb-card-front>
        <nb-card-back>
          <nb-card>
            <nb-card-body>
              {{ item.back }}
            </nb-card-body>
          </nb-card>
        </nb-card-back>
      </nb-flip-card>
    </div>
  </div>
</div>
// app.module.ts
...
import { FormsModule } from '@angular/forms';
import { NbButtonModule, NbCardModule, NbInputModule, NbLayoutModule, NbThemeModule } from '@nebular/theme';

@NgModule({
  ...
  imports: [
      ...
      FormsModule,
      NbCardModule,
      NbInputModule,
      NbButtonModule
  ],
  ...
})
export class AppModule { }

すると以下のような見た目になりました。

Flash Card App

まとめ

今回は Nebular の提供する UI コンポーネントだけを使ってみましたが、次は Auth や Security の機能も使ってみたいと思います。

Daiki Urata

Daiki Urata

フロントエンド/モバイルアプリなどを主に開発しています。