iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 18
1
Modern Web

從零開始的點餐系統,Google好棒棒系列 第 18

[Day18] Angular 主要概念 - Component 實作(1)

  • 分享至 

  • xImage
  •  

本篇會介紹如何建立 component,以及用一些實際的功能說明上一篇的概念

實作出 layout 所需的 components

在實作 modules 的那篇,有建立了 layout module 了。以下指令的 1 ~ 3 行是到 layout 的資料夾下,建立 containers、components 資料夾,用來準備放置 Container components 與 Presentational components

cd ./layout 
mkdir containers components
cd ./containers 
ng g c layout 
cd ../components
ng g c nav
ng g c header
ng g c sidenav
ng g c footer

將 layout module 匯出

若其他模組想要用到 layout module 的 component,需要先把這些 component 加到 @NgModuleexpoorts (11 行),再以模組為單位加到要用到 component 的 @NgModule imports (24 行)

// layout.module.ts
@NgModule({
  declarations: [
    LayoutComponent,
    NavComponent,
    HeaderComponent,
    SidenavComponent,
    FooterComponent,
  ],
  imports: [SharedModule],
  exports: [LayoutComponent, NavComponent], 
  // LayoutComponent 是 Container components ,他裝著HeaderComponent, SidenavComponent, FooterComponent
  // NavComponent 將會直接給 appComponent 所使用
})
export class LayoutModule {}

// app.module.ts
@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    LayoutModule, // 匯入 LayoutModule
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

使用來自 layout module 的 components

再來我們可以直接在 app.component.html,加入 來自 layout module 的 components

本系列不介紹 css ,所以 css 的部分可以直接查看 styles.scss 或 各個 component 的 scss 檔案

<!-- app.component.html -->
<app-nav class="mat-elevation-z6"></app-nav>
<app-layout></app-layout>

完成 nav component

回到 layout module 的 components,我們先實作 nav component,第二行是 material 套件的按鈕,css 就到今日程式碼裡面查看囉

<!-- nav.component.html -->
<nav class="nav-header">
  <a mat-flat-button color="primary" >My Group Buying System</a>
  <div class="flex-spacer"></div>
</nav>

完成 layout component

這一步就要開始注意了,我們把 layout component 當作 Container,所以要把其他還沒用到的 component 放進來,並更新每個 component 的內容(包含 ts、html、scss 三個檔案)。其中比較值得一提的是第 2 行,透過 Property binding
把值傳給 header component,在 header component 也要設定 @Input() 來去接收這個值 (header.component.ts 第 8 行)

<!-- layout.component.html -->
<app-header [headText]="'測試標頭'"></app-header>
<app-sidenav></app-sidenav>
<app-footer></app-footer>

<!-- header.component.html -->
<header class="primary-header component-page-header">
  <h1>{{headText}}</h1>
</header>

<!-- sidenav.component.html -->
<div class="viewer-nav">
  <div class="viewer-nav-content">
    <mat-selection-list [multiple]="false">
      <mat-list-option class="list-item">商家菜單</mat-list-option>
      <mat-list-option class="list-item" >團購活動</mat-list-option>
    </mat-selection-list>
  </div>
</div>

<!-- footer.component.html -->
<footer class="footer">
  <div class="footer-list"></div>
</footer>
// header.component.ts
@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {
  @Input() headText;
}

為商家管理功能做準備

下一篇會開發商家管理的功能,這個功能會出現在下圖 main 的區域

所以下調整一下 layout component 的 html 與 css,因為還沒有講到路由,所以先暫時用 ng-content投射(第 5 行)的方式來代替

<div class="sidenav-inner-content">
  <app-header [headText]="'測試標頭'"></app-header>
  <main class="sidenav-body-content">
    <app-sidenav></app-sidenav>
    <ng-content></ng-content>
  </main>
  <app-footer></app-footer>
</div>

結語

在這次的練習中大概可以看到 component 的樹狀結構( app > layout > header、sidenav、footer),也帶有一些 Container components 與 Presentational components 的溝通( layout > header,用 @Input() 傳值 ),下一篇將會再帶出如何用 @Output() 溝通。
今日練習的程式碼可參考這裡


上一篇
[Day 17] Angular 主要概念 - Component 介紹
下一篇
[Day19] Angular 主要概念 - Component 實作(2)
系列文
從零開始的點餐系統,Google好棒棒30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言