Angular?服務(wù)器端渲染錯誤消息localStorage?is?not?defined解決分析
TypeScript調(diào)用localStorage
在 Angular 應(yīng)用開發(fā)中,我們在 TypeScript 代碼里調(diào)用 localStorage.
它通過 key 從 local storage 中檢索數(shù)據(jù)。 但是在服務(wù)器上,此代碼崩潰并顯示錯誤消息:
ReferenceError: localStorage is undefined
在服務(wù)器上運行 Angular 應(yīng)用程序時,全局空間中缺少標(biāo)準(zhǔn)瀏覽器 API.
例如,在服務(wù)器端渲染模式下,開發(fā)人員不能像在客戶端渲染環(huán)境下那樣,直接訪問全局文檔對象。 要獲得對文檔的引用,必須使用 DOCUMENT 令牌和 Angular 依賴注入機(jī)制 DI.
不要通過全局空間使用瀏覽器 API,而是通過 DI 來替換或禁用瀏覽器實現(xiàn),以便在服務(wù)器上安全使用這些 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 令牌。
錯誤分析
但是當(dāng)我們在服務(wù)器上運行這段代碼時,我們會得到一個錯誤。
只需從 AppServerModule 的 providers 中添加來自 @ng-web-apis/universal 包的 UNIVERSAL_LOCAL_STORAGE,并通過令牌 LOCAL_STORAGE,這樣就能獲得服務(wù)器的 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、目標(biāo)平臺,并了解類的公共屬性。此屬性將在模板中與 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è)務(wù)邏輯。
以上就是Angular 服務(wù)器端渲染錯誤消息localStorage is not defined解決分析的詳細(xì)內(nèi)容,更多關(guān)于Angular 服務(wù)器端渲染錯誤消息解決的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Angular2使用Angular-CLI快速搭建工程(二)
這篇文章主要介紹了Angular2使用Angular-CLI快速搭建工程(二),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05
Angular中的結(jié)構(gòu)指令模式及使用詳解
這篇文章主要為大家介紹了Angular中的結(jié)構(gòu)指令模式及使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
Angular企業(yè)級開發(fā)——MVC之控制器詳解
本篇文章主要介紹了Angular企業(yè)級開發(fā)——MVC之控制器詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02
詳解Angular2學(xué)習(xí)筆記之Html屬性綁定
本篇文章主要介紹了詳解Angular2學(xué)習(xí)筆記之Html屬性綁定,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01
AngularJS實現(xiàn)頁面跳轉(zhuǎn)后自動彈出對話框?qū)嵗a
這篇文章主要介紹了AngularJS實現(xiàn)頁面跳轉(zhuǎn)后自動彈出對話框?qū)嵗a,然后在文章下面給大家介紹了angularjs頁面加載后自動彈窗的實例代碼,感興趣的朋友參考下吧2017-08-08
詳解AngularJS跨頁面?zhèn)髦担╱i-router)
本篇文章主要介紹了詳解AngularJS跨頁面?zhèn)髦担╱i-router),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08

