選單
GSS 技術部落格
在這個園地裡我們將從技術、專案管理、客戶對談面和大家分享我們多年的經驗,希望大家不管是喜歡或是有意見,都可以回饋給我們,讓我們有機會和大家對話並一起成長!
若有任何問題請來信:gss_crm@gss.com.tw
5 分鐘閱讀時間 (949 個字)

Angular #5 - Services and Components[2]

shutterstock_198004562
  • 前一篇主要針對 Service 作了以下處理:

    • 首先當然是定義它長怎樣,其中包含:

      • 它的成員變數方法
      • 它引用到的 Module
      • 以及掛上相關的 Decorator
      • 最後是一個 StockInterface
        • 其他 Component 透過 此 service 拿資料時的型態
        • 有點類似 Java 的 JacksonMapper,在發 XHR request 的時候會自動把收到的 JSON 轉成 StockInterface
    • 那麼定義完之後,我們也在 app.module.ts import註冊了這個 Service,想必接下來就是要使用它了

      • 在使用它之前我們必須先建立一個 Component,用來顯示一張股票的基本資訊

      • 這個 Component 存在的目的是:

        • 接收資料並顯示它,資料的來源會是它的 Component
        • 依據傳進來的資料內容動態決定要加上紅或綠的背景色
        • 格式化輸出資料的內容
      • 建立 Component 的語法如下:

          ng generate component componenets/summary
        • 此時在 src/app/components/summary 這個目錄底下會產出 SummaryComponent 相關的檔案,理論上有4個,分別是:

          • summary.component.html
          • summary.component.ts
          • summary.component.spec.ts
          • summary.component.css
        • 接著在 summary.component.html 中填入以下內容

            <div
              class="mdl-card stock-card mdl-shadow--2dp"
              [ngClass]="{ increase: isPositive(), decrease: isNegative() }"
              style="width: 100%"
            >
              <span>
                <div class="mdl-card__title">
                  <h4 style="color: #fff; margin: 0">
                    {{ stock?.symbol?.toUpperCase() }}<br />
                    {{ stock?.lastTradePriceOnly | currency: "USD":"symbol":".2" }}<br />
                    {{ stock?.change | currency: "USD":"symbol":".2" }} ({{
                      stock?.changeInPercent | percent: ".2"
                    }})
                  </h4>
                </div>
              </span>
            </div>
          • [ngClass] 是一種叫 Directive 的屬性,在使用的時候可以改變 HTML 元素的行為(在這是套上不同的 CSS)
          • Controller(summary.component.ts) 預期要有一個屬性叫 stock, 它是一個擁有諸多屬性值的物件
          • 雙花括號(Doubly curly braces)語法是用來在頁面上呈現資料的, 稱作 Interpolation
          • ?. 會在屬性不存在的時候不顯示任何資料,不會拋出錯誤,稱作 Safe navigation operator
          • 大部份的 javascript 語法在 Angular 中都可以被使用
          • 另外一種 interpolation 是透過 pipes 達成的, 它可以用來對輸出的內容作格式化(e.g. 貨幣格式、百分比格式)
        • 接著在 controller 中輸入以下內容:

            import { Component, Input, OnInit } from '@angular/core';
          
            @Component({
              selector: 'summary',
              templateUrl: './summary.component.html',
              styleUrls: ['./summary.component.css']
            })
            export class SummaryComponent implements OnInit {
          
              constructor() { }
          
              ngOnInit(): void {
          
              }
          
              @Input() stock: any;
          
              isNegative() {
                return this.stock && this.stock.change < 0;
              }
          
              isPositive() {
                return this.stock && this.stock.change > 0;
              }
          
            }
          • 首先我們引用(import)了 Component, Input, Oninit
          • @Input() 指的是可以從 Component 取得資料, 舉例來說:
              <summary [stock]="stockData"></summary>
            • AppComponent 把 stockData 設定到 SummaryComponent 的 stock 這個屬性
            • 這也是為什麼 SummaryComponent 中定義了 @Input() stock:any
        • 再來我們在 summary.component.css 檔中填入以下內容:

            :host .stock-card {
                background: #333333;
            }
            :host .stock-card.increase {
                background: #558B2F;
            color: #fff;
            }
            :host .stock-card.decrease {
                background: #C62828;
            color: #fff;
            }
          • :host 是指這些 CSS 只會作用在 shadow DOM, 更多的資訊可以看此連結
      • 我們終於可以在 AppComponent 裡使用 StockService 了

        • app.component.ts 的內容如下

            import { Component } from '@angular/core';
            import { StocksService, StockInterface } from './services/stocks.service';
          
            @Component({
              selector: 'app-root',
              templateUrl: './app.component.html',
              styleUrls: ['./app.component.css']
            })
            export class AppComponent {
              title = 'stocks';
              stocks: Array<StockInterface>;
          
              constructor(private service: StocksService) {
                service.load(['AAPL']).subscribe(
                  (stocks) => {
                    this.stocks = stocks;
                  }
                )
              }
            }
          • 先引用 modules(StockInterface, StockService)
          • 再來在建構子中 注入 service
      • Service 都架好之後,來處理 View 的部份吧

          <div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
            <header class="mdl-layout__header">
              <div class="mdl-layout__header-row">
                <span class="mdl-layout-title">Stock Tracker</span>
                <div class="mdl-layout-spacer"></div>
                <nav class="mdl-navigation mdl-layout--large-screen-only">
                  <a class="mdl-navigation__link">Dashboard</a>
                  <a class="mdl-navigation__link">Manage</a>
                </nav>
              </div>
            </header>
            <main class="mdl-layout__content" style="padding: 20px" *ngIf="stocks">
              <summary [stock]="stocks[0]"></summary>
            </main>
          </div>
        • selector 被定義在 summary.component.ts,跟我們在這使用它的方式一樣,它是個自定義的 HTML 標籤
        • 特別留意 ngIf *directive, 只有在 **stocks 不是 undefined 而且有值的情況下這個 component 才會被顯示
        • 第 13 行 顯示 stocks[0](AppComponent 傳入的資料) 綁定到 SummaryComponent 的 stock 屬性(還記得 @Input() 嗎?)
      • 此時看到的畫面應該如下圖:

  • 小結一下:

    • 這篇做了什麼呢?
      • 新增了一個 Component(語法還記得嗎?)
      • 針對該 Component 定義了一個 @Input 屬性
      • 在 AppComponent 使用的 StockService
      • AppComponent 將取得到的資料傳給 SummaryComponent,並帶出第一筆股票的資料
      • 股票的資料透過 CurrencyPipe 與 PercentPipe 顯示出貨幣與百分比的資訊
      • 透過 ngClass 在漲的時候是綠底,跌的時候是紅底
      • *ngIf 判斷是否要顯示資料
Angular #6 - Services and Components[3]
Angular #4 - Services 與 Components[1]

相關文章

 

評論 2

Guest - Ray 於 2021/07/19, 週一 17:58

您好,
我用 Angular 12 跟著做,
但在這行
會出現 Can't bind to 'stock' since it isn't a known property of 'summary'
第一次跟著做, 第二次直接 copy 程式, 都有上一列的 Error
不知還有哪裡要調整
謝謝

您好, 我用 Angular 12 跟著做, 但在這行 會出現 Can't bind to 'stock' since it isn't a known property of 'summary' 第一次跟著做, 第二次直接 copy 程式, 都有上一列的 Error 不知還有哪裡要調整 謝謝
George Chou (周孚陽) 於 2021/07/26, 週一 08:48

嗨,先確定 summary.component.ts 裡有 *stock* 這個屬性
1) 如果確定有,那試著 ng serve 看能不能啟動本機的 nodejs server,如果可以代表是 VSCode 的 Bug,把那一個頁籤關掉再重開 VSCode 就可以了
2) 如果沒有,補上再試試,如果還是一樣的錯誤先看看 1) 行不行得通
3) 如果確定有 *stock* 這個屬性,而且 ng serve *不會* 過,那就看看是不是少了 import

以上,還有問題再說一聲^^"

嗨,先確定 summary.component.ts 裡有 *stock* 這個屬性 1) 如果確定有,那試著 ng serve 看能不能啟動本機的 nodejs server,如果可以代表是 VSCode 的 Bug,把那一個頁籤關掉再重開 VSCode 就可以了 2) 如果沒有,補上再試試,如果還是一樣的錯誤先看看 1) 行不行得通 3) 如果確定有 *stock* 這個屬性,而且 ng serve *不會* 過,那就看看是不是少了 import 以上,還有問題再說一聲^^"
已經注冊了? 這裡登入
Guest
2024/05/20, 週一

Captcha 圖像