使用 Angular Transfer State 的一个具体例子
Using TransferState API in an Angular v5 Universal App
讓我們用一個(gè)具體的例子來(lái)說(shuō)明這篇文章。 我們有一個(gè)天氣應(yīng)用程序,在其側(cè)邊欄中顯示城市列表。 當(dāng)您單擊城市名稱(chēng)時(shí),該應(yīng)用程序會(huì)顯示該城市的當(dāng)前天氣。
因?yàn)槲覀兿M覀兊膽?yīng)用程序是可抓取和可索引的,所以我們使它通用:城市頁(yè)面在服務(wù)器上呈現(xiàn),存儲(chǔ)為 HTML 文件并由 HTTP 服務(wù)器提供服務(wù)。 這些頁(yè)面將包含瀏覽器應(yīng)用程序,因此用戶(hù)可以在加載第一頁(yè)后使用 Angular 的強(qiáng)大功能繼續(xù)在應(yīng)用程序中導(dǎo)航。
您可以按照以下步驟嘗試這個(gè)簡(jiǎn)單的示例。
使用下列命令將這個(gè)例子 clone 到本地:
$ git clone https://github.com/feloy/ng-demo-transfer-state $ cd ng-demo-transfer-state $ git checkout initial構(gòu)建程序:
$ npm install $ ng build -prod $ ng build -prod -app server --output-hashing=none為不同的城市創(chuàng)建不同的頁(yè)面:
$ node render-page.js /Paris > dist/Paris $ node render-page.js /London > dist/London $ node render-page.js /San%20Fransisco > 'dist/San Fransisco'您現(xiàn)在可以使用首選的 HTTP 服務(wù)器為 dist 目錄提供服務(wù)。
現(xiàn)在,如果您直接訪問(wèn)頁(yè)面 http://your-domain/Paris(這是訪問(wèn)者來(lái)自搜索引擎的典型情況),您可以觀察到頁(yè)面閃爍 - 這是因?yàn)閮?nèi)容已經(jīng)存在并且已經(jīng)下載到本地了,然后瀏覽器應(yīng)用程序會(huì)重新加載并再次顯示。
TransferState to the rescue
Angular v5 中引入的 TransferState API 可以幫助解決這種情況。 它可以將數(shù)據(jù)從應(yīng)用程序的服務(wù)器端傳輸?shù)綖g覽器應(yīng)用程序。
為此,服務(wù)器應(yīng)用程序?qū)⒃谒傻?HTML 頁(yè)面中添加我們要傳輸?shù)臄?shù)據(jù)。
包含在此生成的 HTML 頁(yè)面中的瀏覽器應(yīng)用程序?qū)⒛軌蜃x取此數(shù)據(jù)。
在這個(gè)分支查看解決方案。
$ git checkout transfer-data首先在服務(wù)器應(yīng)用上導(dǎo)入 ServerTransferStateModule,在瀏覽器應(yīng)用上導(dǎo)入 BrowserTransferStateModule:
// src/app/app.server.module.ts import {ServerTransferStateModule} from '@angular/platform-server'; [...] @NgModule({imports: [AppModule,ServerModule,ServerTransferStateModule],bootstrap: [AppComponent], }) export class AppServerModule {} // src/app/app.module.ts import { BrowserTransferStateModule } from '@angular/platform-browser'; [...] @NgModule({declarations: [AppComponent, CityComponent],imports: [BrowserModule.withServerTransition({ appId: 'ng-demo-transfer-state-app' }),BrowserTransferStateModule,[...]現(xiàn)在,在為組件提供數(shù)據(jù)的解析器中,我們可以使用 TransferState API:
- 在服務(wù)器上,我們首先注冊(cè) onSerialize 以提供我們將下載的數(shù)據(jù),然后我們從我們的數(shù)據(jù)提供者那里獲取數(shù)據(jù),這里是一個(gè) HTTP GET 請(qǐng)求。
- 在瀏覽器上,我們使用get方法來(lái)獲取server提供的數(shù)據(jù),我們直接提供這些數(shù)據(jù)。 我們還從傳輸狀態(tài)中刪除了提供的數(shù)據(jù),因此頁(yè)面的重新加載將不再使用提供的數(shù)據(jù)。
我們可以通過(guò)調(diào)用 hasKey 方法來(lái)檢測(cè)我們是在服務(wù)器上還是在瀏覽器應(yīng)用程序上。 此方法僅在瀏覽器中返回 true。
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<CityWeather> {const found = this.transferState.hasKey(RESULT_KEY);if (found) {const res = Observable.of(this.transferState.get<CityWeather>(RESULT_KEY, null));this.transferState.remove(RESULT_KEY);return res;} else {this.transferState.onSerialize(RESULT_KEY, () => this.result);const name = route.params['city'];return this.http.get<CityWeather>('https://api.openweathermap.org/data/2.5/weather?q=' + name + '&units=metric&APPID=' + this.key).do(result => this.result = result);}}因?yàn)槲覀兪钦{(diào)用remove方法移除提供的數(shù)據(jù),所以瀏覽器顯示的以下頁(yè)面會(huì)調(diào)用onSerialize方法,但是這個(gè)方法沒(méi)有效果,因?yàn)閠oJson只在服務(wù)端調(diào)用。
一個(gè)更清晰的解決方案是使用 isPlatformServer 和 isPlatformBrowser 方法來(lái)檢測(cè)平臺(tái)并采取相應(yīng)的行動(dòng)。
更多Jerry的原創(chuàng)文章,盡在:“汪子熙”:
總結(jié)
以上是生活随笔為你收集整理的使用 Angular Transfer State 的一个具体例子的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: DNF土豆服务器是什么服务器 土豆服务器
- 下一篇: 什么是 SAP Spartacus UI