iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 9
0
Modern Web

Angular - 從零開始系列 第 9

Angular - 從零開始 - Day9 -實作一個側欄選單與 SPA 頁面

  • 分享至 

  • twitterImage
  •  

angular

本次練習主題

  • 可收合的側欄選單。
  • 建立 service 共享元件功能。
  • 元件與畫面的分類。
  • 路由與子路由的 SPA 應用。

頁面分類練習

這次練習的過程中釐清了一個觀念就是元件與畫面的分離,別於之前所見即所得的寫法,現在要拆成元件與畫面分離,什麼意思? 前輩簡單教我一個記憶法:

要給使用者看到的稱作畫面,不需要看到的稱為元件。

所以先看一下資料夾內容:

folder

可看到資料夾分成 componentpage,下方一堆 app 開頭的是這支程式的母元件與路由,最下面的 index.html 是整個網頁的入口。

重點在元件與頁面這兩個資料夾

先看一下這次練習的畫面:

index

看起來相當簡單的畫面,目前預設為 Home 的內容,當我選擇 System 標籤,下方會出現兩個選項,點擊該選項後會跑出相對應的內容。

Home

home

System/User

user

System/Group

group

點擊選單右上角的標籤也會進行收合,

close

元件資料夾

下方為元件資料夾的內容,這邊分類的內容就是 aside 的惻欄部分,

component

因為這兩個部分只有單純元件顯示,不是一直改變的內容,所以區分成在元件,而在元件部分又再將上方的 LOGO 與下方的選單拆成兩個元件,也就是 aside 主元件跟 aside-nav 子元件。

建立 service 共用功能

Angular 筆記 - Service 服務元件的基本認識有紀錄如何建立服務元件,而在這邊的服務元件中寫入點擊事件跟判斷是否收合選單,因為兩個介面都使用類似的邏輯,所以就寫在同一個服務元件內。

aside-nav HTML

可看見有事件繫結與屬性繫結的寫法,概念有點像寫 jQuery 在 CSS 中給予對應的 className,然後在用程式邏輯判斷增加 className 後的效果。

<ul class="nav">
  <li class="btn">
    <button class="btn">
      <a routerLink="/home/home-text">Home</a>
    </button>
  </li>
  <li class="btn">
    <button type="button" class="btn" (click)="featureSvc.toggleList()">
      System
    </button>
    <ul class="systemList" [class.show]="featureSvc.showList()">
      <li>
        <button class="btnUser">
          <a routerLink="/system/system-user" routerLinkActive="active"
            >User
          </a>
        </button>
      </li>
      <li>
        <button class="btnGroup">
          <a routerLink="/system/system-group" routerLinkActive="active">
            Group</a
          >
        </button>
      </li>
    </ul>
  </li>
</ul>

service 服務元件

有趣的是在 service 宣告變數不用使用 let 或 const,也可以建立。

export class FeatureService {
  close = false; // nav 是否關閉
  show = false; // 是否出現選單
  constructor() {}

  asideToggle() {
    return this.close; //回傳點擊後布林值
  }

  asideSwitch() {
    this.close = !this.close; //側欄選單開關
  }

  showList() {
    return this.show; //回傳 nav 選單點擊後的布林值
  }

  toggleList() {
    this.show = !this.show; //nav 選單開關
  }
}

這樣就完成了收合選單與項目清單開闔的功能。

路由與子路由呈現 SPA

再來也是這次練習的重頭戲之一,點擊選項讓右邊的畫面呈現對應的內容。

先來看一下路由架構,主要分成以下三大類:

  1. login 路由。
  2. index 路由,沒有寫 path 的原因是預設為起始畫面。
  3. 404 not found 萬用路由
  4. 不管怎麼樣都會回到 home 頁面的萬用路由。

路由的順序是從上讀到下,若找到對應的路徑就會將內容渲染於網頁上。

const routes: Routes = [
  { path: "login", component: LoginComponent },
  {
    path: "",
    component: IndexComponent,
    children: [
      {
        path: "home",
        component: HomeComponent,
        children: [
          {
            path: "home-text",
            component: HomeTextComponent,
          },
          { path: "**", redirectTo: "home-text", pathMatch: "full" },
        ],
      },
      {
        path: "system",
        component: SystemComponent,
        children: [
          {
            path: "system-user",
            component: SystemUserComponent,
          },
          { path: "system-group", component: SystemGroupComponent },
        ],
      },
      { path: "**", redirectTo: "login", pathMatch: "full" },
    ],
  },
  { path: "**", component: PageNotFoundComponent },
  { path: "**", redirectTo: "login", pathMatch: "full" },
];

最複雜的串路由來了

先來看一下頁面資料夾的架構,

page

就是將父與子層的頁面做歸納與相依整理,content 資料夾就是整個右側內容的主資料夾,其中會更換頁面的就是 homecontent-main 資料夾,但 content-main 其實都沒有寫任何東西。

HOME 頁面

Home 頁面又拆了 home-text 的元件,當中就是 component 的串接而已,也就是把 <home-text> 的內容注入在 home 的 html 中。

System

因為此標籤下面有兩個選項要呈現對應的內容,所以這邊為路由的接口,所以要放 <router-outlet> 標籤。

System-User 與 System-Group

就分別顯示預設的文字。

index 主頁面

最重要的就是這一頁了,因為更換內容是在 index 裡面,所以 app-content-main 被替換成 <router-outlet> 標籤,做為入口,其它因為不會更動,就只要元件串接就可以。。

<div class="index">
  <app-aside></app-aside>
  <div class="content">
    <app-content-header></app-content-header>
    <router-outlet></router-outlet>
    <app-content-footer></app-content-footer>
  </div>
</div>

結語

這次練習學習到路由要想著哪一個是頁面進入的接口,並父與子層的關係先建構好,路由也建構完成,彼此的相依順序要釐清,這樣在寫 SPA 與元件拆分才不會搞混,目前架構還沒有寫得非常好,就記錄本次練習做為參考。


上一篇
Angular - 從零開始 - Day8 -Service 服務元件的基本認識
下一篇
Angular - 從零開始 - Day10 -範本參考變數基本認識
系列文
Angular - 從零開始25
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言