iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 12
0
Modern Web

Angular 元件庫 NG-ZORRO 基礎入門系列 第 12

[Angular 元件庫 NG-ZORRO 基礎入門] Day 12 - Hacker News

  • 分享至 

  • xImage
  •  

前言回顧

昨天第一個例子和相關的元件我們已經完成介紹了,接下來我們繼續進行新的 demo 開發,接下來幾天我們會使用 NG-ZORRO 開發 Angular 版本的 Hacker News,過程中會使用一些全新的元件並加以介紹,這也會是我們在進階學習前的最後一個實戰案例,今天我們會來搭建該專案一些必要的配置和介面。

Hacker News

hacker news 是什麼?

Hacker News 是一家關於計算機黑客和創業公司的社會化新聞網站,由保羅·格雷厄姆的創業孵化器 Y Combinator 建立。與其它社會化新聞網站不同的是 Hacker News 沒有踩或反對一條提交新聞的選項(不過評論還是可以被有足夠 Karma 的使用者投反對票);只可以贊或是完全不投票。簡而言之,Hacker News 允許提交任何可以被理解為“任何滿足人們求知慾”的新聞。

官方網站:https://news.ycombinator.com/

https://ithelp.ithome.com.tw/upload/images/20190913/20112829AO2RLMA9g4.png

準備工作

我們可以看到, hacker news 提供了 公共的 API 供我們呼叫,我們可以為其建立一個 service 來管理相關的介面。

建立 service

之前我們講過,對於 http 介面請求 最好是建立獨立的服務(service),可以給我們呼叫和後期維護帶來很大便利。先來建立 servicehacker news 元件。

$ cd ng-zorro-ironman2020
$ ng g c components/demos/hacker-news --skip-import
$ ng g s services/hacker-news

獲取新聞

使用 官方API

檢視 官方 API 文件,檢視基本結構

基本結構

https://hacker-news.firebaseio.com/v0/item/8863.json?print=pretty

{
  "by" : "dhouston",
  "descendants" : 71,
  "id" : 8863,
  "kids" : [ 8952, 9224, 8917, 8884, 8887, 8943, 8869, 8958, 9005, 9671, 8940, 9067, 8908, 9055, 8865, 8881, 8872, 8873, 8955, 10403, 8903, 8928, 9125, 8998, 8901, 8902, 8907, 8894, 8878, 8870, 8980, 8934, 8876 ],
  "score" : 111,
  "time" : 1175714200,
  "title" : "My YC app: Dropbox - Throw away your USB drive",
  "type" : "story",
  "url" : "http://www.getdropbox.com/u/2/screencast.html"
}

Tips:提供給大家一個快速將 json 格式格式化為 Angular interface 結構的網站 jsontots

export interface IStory {
  by: string;
  descendants: number;
  id: number;
  kids: number[];
  score: number;
  time: number;
  title: string;
  type: string;
  url: string;
}
新聞資料列表

檢視 API 我們得知,訪問 https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty 得出 story 的 id 列表:

[ 20960832, 20960721, 20959831, 20958397, ... ]

但是這並不是我們想要的結果,我們希望返回的是包含總新聞資料量和新聞詳情列表的結果,比如:

{
  total: 100,
  data: IStory[]
}

從上面我們已經得知如何通過 ID 來獲取新聞詳情,通過 RxJS 的 mergeMapforkJoin 操作符我們可以輕易地解決這個問題(該部分內容我們不展開討論,有興趣的同學可以專門搜尋 RxJS 相關文章學習),返回需要查詢的新聞 id 內容。
看一下在 hacker-news.service.ts 裡我們是如何實現的(為了減少單次請求次數,在程式碼中我們加入了前端分頁引數):

getStories(page: number = 1, pageSize: number = 20, type = IBaseStoryType.TOP): Observable<IResultList> {
  return this.http.get<any>(`https://hacker-news.firebaseio.com/v0/beststories.json?print=pretty`).pipe(
	mergeMap((ids) => forkJoin([of(ids.length), ...ids.slice((page - 1) * pageSize, page * pageSize).map(id => this.getStory(id))])),
	map(data => {
	  return {
		total: data[0],
		data: data.slice(1)
	  };
	})
  );
}
getStory(itemId: number): Observable<IStory> {
  return this.http.get<IStory>(`https://hacker-news.firebaseio.com/v0/item/${itemId}.json?print=pretty`);
}

我們可以看到 mergeMap 拿到介面返回的 id 陣列後通過 forkJoin 請求了各個 id 的詳情並返回,在返回陣列的第一項我們存放了總資料量(僅僅是為了前端分頁設計可暫時忽略),看一下 map 之後的結果:

{
    "total":200,
    "data":[
        {
            "by":"anigbrowl",
            "descendants":550,
            "id":20955103,
            "kids":[
                20956457,
                20955562,
			  	...
            ],
            "score":1799,
            "time":1568314973,
            "title":"California bans private prisons",
            "type":"story",
            "url":"https://www.theguardian.com/us-news/2019/sep/12/california-private-prison-ban-immigration-ice"
        },
	  	...
    ]
}

但是這種方案有個弊端,就是我們每次都要發起 20 次 http 請求然後返回結果陣列,導致很麻煩,不過我們倒是從這個方法中能瞭解一些 RxJS 操作符的使用方式。

那麼有沒有一個介面就返回所有我們想要的資料呢?答案當然是肯定的。

使用 algolia API

同樣的它也提供了一些 API 來供我們使用,不同於上述 API,這個介面直接返回了詳情給我們使用,無需我們二次處理,看一下 線上返回資料,返回瞭如下結構,hits 屬性即為命中的結果(為了簡潔我刪除了部分屬性):

{
    "hits":[
        {
            "title":"Stephen Hawking has died",
            "url":"http://www.bbc.com/news/uk-43396008",
            "author":"Cogito",
            "points":6015,
            "story_text":null,
            "comment_text":null,
            "num_comments":436,
            "_tags":[
                "story",
                "author_Cogito",
                "story_16582136"
            ],
            "objectID":"16582136",
            "_highlightResult":{
                "title":{
                    "value":"Stephen Hawking has died",
                    "matchLevel":"none",
                    "matchedWords":[]
                },
                "url":{
                    "value":"http://www.bbc.com/news/uk-43396008",
                    "matchLevel":"none",
                    "matchedWords":[
                    ]
                },
                "author":{
                    "value":"Cogito",
                    "matchLevel":"none",
                    "matchedWords":[
                    ]
                }
            }
        }
    ],
    "nbHits":18914697,
    "page":0,
    "nbPages":1000,
    "hitsPerPage":1,
    "query":"",
}

檢視單個新聞的詳情:https://news.ycombinator.com/item?id=20961506,返回結構如下,我們還可以直接在詳情中得到評論內容。

export interface IReplyComment {
  id: number;
  created_at: Date;
  created_at_i: number;
  type: string;
  author: string;
  title?: any;
  url?: any;
  text: string;
  points?: any;
  parent_id: number;
  story_id: number;
  children: IReplyComment[];
  options: any[];
}

export interface IStory {
  id: number;
  created_at: Date;
  created_at_i: number;
  type: string;
  author: string;
  title: string;
  url: string;
  text?: any;
  points: number;
  parent_id?: any;
  story_id?: any;
  children: IReplyComment[];
  options: any[];
}

總結 & 預告

今天我們做了一些專案開始前的必備準備工作,包括 API 介面, interface 設計、背景知識等,既然介面已經設計完成,我們在明天也會正式開始 hacker news 專案的開發。

相關資料

Github 今日線上程式碼:https://github.com/simplejason/ng-zorro-ironman2020/tree/day-12-hacker-news-start
Hacker News:https://news.ycombinator.com/
Algolia API:https://hn.algolia.com/api


上一篇
[Angular 元件庫 NG-ZORRO 基礎入門] Day 11 - Drawer
下一篇
[Angular 元件庫 NG-ZORRO 基礎入門] Day 13 - Hacker News: List
系列文
Angular 元件庫 NG-ZORRO 基礎入門30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言