Angular?服務器端渲染錯誤消息localStorage?is?not?defined解決分析
TypeScript調(diào)用localStorage
在 Angular 應用開發(fā)中,我們在 TypeScript 代碼里調(diào)用 localStorage.
它通過 key 從 local storage 中檢索數(shù)據(jù)。 但是在服務器上,此代碼崩潰并顯示錯誤消息:
ReferenceError: localStorage is undefined
在服務器上運行 Angular 應用程序時,全局空間中缺少標準瀏覽器 API.
例如,在服務器端渲染模式下,開發(fā)人員不能像在客戶端渲染環(huán)境下那樣,直接訪問全局文檔對象。 要獲得對文檔的引用,必須使用 DOCUMENT 令牌和 Angular 依賴注入機制 DI.
不要通過全局空間使用瀏覽器 API,而是通過 DI 來替換或禁用瀏覽器實現(xiàn),以便在服務器上安全使用這些 API.
參考下面的代碼:
import {Component, Inject, NgModule} from '@angular/core'; import {LOCAL_STORAGE} from '@ng-web-apis/common'; @Component({...}) export class SomeComponent { constructor(@Inject(LOCAL_STORAGE) localStorage: Storage) { localStorage.getItem('key'); } }
上面的示例使用來自 @ng-web-apis/common 包的 LOCAL_STORAGE 令牌。
錯誤分析
但是當我們在服務器上運行這段代碼時,我們會得到一個錯誤。
只需從 AppServerModule 的 providers 中添加來自 @ng-web-apis/universal 包的 UNIVERSAL_LOCAL_STORAGE,并通過令牌 LOCAL_STORAGE,這樣就能獲得服務器的 localStorage 實現(xiàn)。
import { NgModule } from '@angular/core'; import { ServerModule, } from '@angular/platform-server'; import { AppModule } from './app.module'; import { AppComponent } from './app.component'; import { UNIVERSAL_LOCAL_STORAGE } from '@ng-web-apis/universal'; @NgModule({ imports: [ AppModule, ServerModule, ], providers: [UNIVERSAL_LOCAL_STORAGE], bootstrap: [AppComponent], }) export class AppServerModule {}
看下面這段條件渲染代碼:
<> @Component({ selector: 'ram-root', template: '<some-сomp *ngIf="isServer"></some-сomp>', styleUrls: ['./app.component.less'], }) export class AppComponent { isServer = isPlatformServer(this.platformId); constructor(@Inject(PLATFORM_ID) private platformId: Object){} }
這個 Angular Component 需要獲取 PLATFORM_ID、目標平臺,并了解類的公共屬性。此屬性將在模板中與 ngIf 指令一起使用。
優(yōu)雅實現(xiàn)
創(chuàng)建injection token
<> export const IS_SERVER_PLATFORM = new InjectionToken<boolean>('Is server?', { factory() { return isPlatformServer(inject(PLATFORM_ID)); }, });
創(chuàng)建自定義指令
@Directive({ selector: '[ifIsServer]', }) export class IfIsServerDirective { constructor( @Inject(IS_SERVER_PLATFORM) isServer: boolean, templateRef: TemplateRef<any>, viewContainer: ViewContainerRef ) { if (isServer) { viewContainer.createEmbeddedView(templateRef); } } }
然后直接在 Component 上使用這個 structure Directive 就可以了:
<> @Component({ selector: 'ram-root', template: '<some-сomp *ifIsServer"></some-сomp>', styleUrls: ['./app.component.less'], }) export class AppComponent {}
額外的屬性已從組件中移除。Component 模板現(xiàn)在更簡單了,只用專注于它要實現(xiàn)的業(yè)務邏輯。
以上就是Angular 服務器端渲染錯誤消息localStorage is not defined解決分析的詳細內(nèi)容,更多關于Angular 服務器端渲染錯誤消息解決的資料請關注腳本之家其它相關文章!
相關文章
解決angular2 獲取到的數(shù)據(jù)無法實時更新的問題
今天小編就為大家分享一篇解決angular2 獲取到的數(shù)據(jù)無法實時更新的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08angularjs1.X 重構controller 的方法小結(jié)
這篇文章主要介紹了angularjs1.X 重構controller 的方法小結(jié),非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-08-08深入淺析angular和vue還有jquery的區(qū)別
vue是一個漸進式的框架, 是一個輕量級的框架而angular是一個mvc框架, 各有千秋,下面小編通過本文給大家介紹angular和vue還有jquery的區(qū)別,感興趣的朋友一起看看吧2018-08-08Angularjs 實現(xiàn)動態(tài)添加控件功能
這篇文章主要介紹了Angularjs 實現(xiàn)動態(tài)添加控件功能,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-05-05AngularJS中$injector、$rootScope和$scope的概念和關聯(lián)關系深入分析
這篇文章主要介紹了AngularJS中$injector、$rootScope和$scope的概念和關聯(lián)關系,結(jié)合實例形式較為深入的分析了$injector、$rootScope和$scope的概念、功能、使用方法及相互之間的關系,需要的朋友可以參考下2017-01-01詳解angular2采用自定義指令(Directive)方式加載jquery插件
本篇文章主要介紹了詳解angular2采用自定義指令(Directive)方式加載jquery插件 ,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-02-02AngularJS數(shù)據(jù)源的多種獲取方式匯總
在AngularJS中獲取數(shù)據(jù)源的方式有很多種,本文給大家整理幾種獲取數(shù)據(jù)源的方式,對angularjs獲取數(shù)據(jù)源的方式相關知識感興趣的朋友一起學習吧2016-02-02