iT邦幫忙

2023 iThome 鐵人賽

DAY 10
0
Modern Web

從0開始的的Angular站台架設-Stnadalone 系列 第 10

D9 我叫軍團,因為我們人數眾多 - ngFor與 ngSwitchCase與pipe

  • 分享至 

  • xImage
  •  

再說完ngIf之後,接下來我們來談談ngFor。

ngFor顧名思義,我們可以利用這個裝飾器進行element的迴圈生成,這部分的功能與React 的 for迴圈和Vue的 v-for,是差不多的用途。

看看我們在Header上的分類以及下方各式各樣不同的商品,一個一個弄也太麻煩了,你要保證每一個樣式與內容沒有出錯,檢查上也比較繁瑣,但假如你家老闆是看Code的行數進行績效評定的話,請無限複製貼上,我非常歡迎,並拜託跟我說說那家公司的名字究竟叫什麼。

接下來我們以header的categorys進行開發範例。


首先我會先思考categorys的資料結構設計,為了要讓它可以迴圈,所以它一定會是個Array


Array<categoryType>

那categoryType呢?

使用者的操作情境一定會是希望當它點擊的時候下方商品進行更新或是挑轉頁面,畫面的呈現內容是他想要看到的商品,所以除去顯示的文字contant以外,我們需要有一個ID值作為我們查找分類商品與跳轉頁面的API依據,所以整個categoryType Object將會是以下結構

 categories:Array<{
    categoryID:number,
    categoryName:string
  }>=[
    {
      categoryID:0,
      categoryName:'All'
    },
    {
      categoryID:1,
      categoryName:'Top Sell'
    },
    {
      categoryID:2,
      categoryName:'Gift Cards'
    },
    {
      categoryID:3,
      categoryName:'Sell'
    }
  ]

這個寫法是TypeScript的型別宣告,後端的捧油特別是使用強型別語言的朋友一定會有熟悉感甚至是回家的感覺。

Angular作為主要倡導強型別前端開發的前端框架,與其它前端開發方式不同,它已經整合了ts的開發模式。

TypeScript的型別要講又可以講一個鐵人賽,所以這邊讓我抖抖包袱然後下次一定。

但可以說的是本次開發會以interface作為主要的型別宣告,後面會簡單用個一天講一下typeScript最常見的三種型別宣告 type、interface、class

回過頭來續說ngfor,在實務操作上十分簡單,只要把我們要進行迴圈的陣列放入到ngFor之中

然後我們只要在element中放入要顯示的內容就好了。

<ul>
  <li *ngFor="let item of categories">
    <span *ngIf="item.categoryID===7">
        大大大優惠{{ item.categoryName }} //{{}}這個用法叫做插值法,我們可以在裡面進行簡單的JS物件處理

      </span>
    {{ item.categoryName }}
  </li>
</ul>

怎麼樣,是不是很簡單?

那假如我這個category想要在html上隱藏起來,但又因為在其他function中有著其他的用途不能輕易的變動資料結構,這時候我們該怎麼辦?

我們昨天有說到的ngif好像就能用了,對不對?

恩,這是一個思路沒有錯,但同樣作為動態渲染的element,它被ngfor渲染出來的時候,它與ngIf的渲染判斷衝突時,我應該優先聽誰的?

再來想想看Angular作為雙向綁定特性的開發框架,當資料重新異動時,ngIf的判斷條件又重新更新時,又是誰的時點具有較重的加權?

關於這點開發者也表示,就你們這群人一堆問題,給我把兩個內容隔開好嗎?

所以當我們想要利用ngIf作為子元件渲染與否判別的時候,我們可以在實際要放內容的地方用一個element包裹起來並用ngIf進行呈現判斷。

那假如我今天用的Array是更加複雜的goodItem呢?

這個物件中的結構如下

{
    categoryID:number,
    categoryName:string,
    goodID:string,
    goodName:string,
    orginPrice:number,
    salePrice:number,
    discountNumber:number,
    discountString:string,
    onSale:boolean
}

需求: 我希望可以根據類別的不同在我折扣為多少的時候有特別鮮豔的顏色。

...

我用我的血壓開了個彩帛鋪的∶紅的,黑的,紫的,都綻將出來給您老看行不?

為了拯救我們自己不會像鎮關西一樣成佛做祖快哉快哉,我們這邊來使用ngSwitchCase協助我們達成如上的需求

ngSwitchCase,顧名思義,它可以讓我們在element上做的實作如同swtch的功能,具體範例如下

<div>
  <div *ngFor="let item of goodItems">
    <div [ngSwitch]="item.categoryID">
      <span *ngSwitchCase="7">
        {{ item.categoryName }}
      </span>
      <span *ngSwitchCase="8">
        {{ item.categoryName }}
      </span>
      <span *ngSwitchDefault>
        {{ item.categoryName }}
      </span>
    </div>
  </div>
</div>

哇,傑克我們做到了

其實使用這個方式的最主要原因還有另外一點,現在我們已經可以辨別出哪個商品分類了,在做一些行銷行為的追蹤時,我可以在複雜的情境中提前先切出各種不同的情境,將當下的消費者行為參數回報給GA或是其他家的行銷資料追蹤紀錄API

說完了渲染的ngIf、ngFor、ngSwitchCase後,我們來簡單說說我們渲染出來的東西怎麼在頁面中顯示

{{}} Interpolation a.k.a插值法

讓我們省去使用 innerHtml 與 innerText的屬性使用,得以在Html上進行呈現,並能在html之中做簡單的property建構函式運用。

這部分跟JS的Template literals的概念有點類似,我都可以在我的操作域內對於該物件進行操作與格式化成我想要的資訊。

{{}}中經常與ngModule和pipe一同出現,ngModule將會在明天與InPut與OutPut一起講,今天我們將著重在template上的資料渲染pipe

管道(Pipes)是一種用於在模板中轉換數據的機制。它們用於對模板中的變數執行轉換操作,以便在呈現數據時進行格式化、過濾或轉換。

我們可以透過pipe置換我們要在葉面呈現的資料,不必特憋在花力氣去做forEach或請後端協助提供格式

{{ birthday | date:dd/mm/yyyy | uppercase}}

Angular本身已經有內建部分的pipe,從上面的範例中我們可以得知pipe是可以進行串聯並在其中的pipe賦予pipe的屬性,除此之外piep也能進行Observable的async的處理

 <div
    *ngIf="slideMenuStatus$ | async as slideMenuStatus">
 </ div>

我們也可以透過pipe幫我們過濾掉不要的商品折扣,像這種的就需要我們自行建置pipe了

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'goodSaleOff', standalone: true })
export class GoodSaleOffPipe implements PipeTransform {
  transform(goodDiscount:number,filterCount:number) {
    return goodDiscount.filter((good) => good.discount <= filterCount);
  }
}

這時候前端可以這樣子寫

<div>
  <div *ngFor="let item of (goodDiscountItems | goodSaleOff:0.5)">
    {{item}}
  </div>
</div>

今天大概就先講到這樣,明天我們將會從ngModulle開始說說input、output與LifeCycle~


上一篇
D8 我跳進來,我又跳出去了 - ngIf [hidden] ngClass與ngStyle
下一篇
D10 川流不息的資料流 Input() and @Output()與他們的生命週期
系列文
從0開始的的Angular站台架設-Stnadalone 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言