當前位置:
首頁 > 科技 > 手把手教你用ngrx管理Angular狀態(下)

手把手教你用ngrx管理Angular狀態(下)

預覽組件

現在讓我們來創建標籤預覽組件,預期效果如下:

用命令行來創建TagPreviewComponent組件的手腳架,它將是Create頁面和Complete頁面的子組件,所以把這個組件放在app文件夾下:

$ ng g component tag-preview

預覽組件腳本

// src/app/tag-preview/tag-preview.component.ts

import{Component,OnChanges,Input}from @angular/core ;

import{PetTag}from ./../core/pet-tag.model ;

@Component({

selector: app-tag-preview ,

templateUrl: ./tag-preview.component.html ,

styleUrls:[ ./tag-preview.component.css ]

})

exportclassTagPreviewComponentimplementsOnChanges{

@Input()petTag:PetTag;

imgSrc= ;

tagClipText:string;

gemsText:string;

constructor(){}

ngOnChanges(){

this.imgSrc=`/assets/images/${this.petTag.shape}.svg`;

this.tagClipText=this.boolToText(this.petTag.clip);

this.gemsText=this.boolToText(this.petTag.gems);

}

privateboolToText(bool:boolean){

returnbool? Yes : No ;

}

}

TagPreviewComponent是接受父組件CreateComponent輸入的木偶子組件,它並不向父組件傳遞數據。引入Input裝飾器以及OnChanges生命周期函數鉤子,同時需要引入PetTag表明輸入的類型。

TagPreviewComponent類需要實現OnChanges介面,也就是在該類中調用ngOnChanges方法。每當組件的輸入參數發生變化時,ngOnChanges就會執行。這樣才能實現在用戶編輯修改的時候實時預覽效果。

從父組件中接受的數據@Input() petTag是個狀態對象,數據類型是之前定義的PetTag。比如,一個petTag對象可能是這樣的:

{

shape: bone ,

font: serif ,

text: Fawkes ,

clip:true,

gems:false,

complete:false

}

我們希望友好直觀地展示數據,所以我們將會顯示標籤的形狀圖片,文案,以及是否包含了clip和gems。

當用戶進行操作時,需要專門設置一下圖片的路徑以及clip和gems的文案(Yes或者No)。輸入是由CreateComponent對tagState$這個可觀察對象的訂閱提供。

預覽組件模版

{{petTag.text}}

Tag clip:{{tagClipText}}

Gems:{{gemsText}}

預覽將會在用戶選擇標籤形狀之後顯示。用一個shape樣式類來控制顯示正確的形狀圖片,同時也會顯示標籤的文字,字體是用font樣式類來控制的。最後,直接標註出用戶是否選擇了包含clip,gems兩個特性。

預覽組件樣式

/* src/app/tag-preview/tag-preview.component.css */

.tagView-wrapper{

padding-top:20px;

}

.tagView{

height:284px;

position:relative;

width:100%;

}

img{

display:block;

height:100%;

margin:auto;

width:auto;

}

.text{

font-size:48px;

position:absolute;

text-align:center;

text-shadow:1px 1pxrgba(255,255,255,.8);

top:99px;

width:100%;

}

.bone.text,

.rectangle.text{

font-size:74px;

top:85px;

}

.sans-serif{

font-family:Arial,Helvetica,sans-serif;

}

.serif{

font-family:Georgia, Times New Roman ,Times,serif;

}

除了一些定位之外,我們根據不同形狀設置了不同的字體大小,根據用戶選擇設置不同字體。

現在,我們可以添加到Create頁面了。

將預覽組件添加至Create頁面

...

[petTag]="petTag">

方括弧[...]單向綁定屬性,我們在CreateComponen組件的訂閱tagStateSubscription中已經創建了petTag,現在將其傳遞給預覽組件。

現在,我們應該可以看到標籤的實時預覽效果了:

GIF/69K

提交完成標籤

有了標籤生成器和標籤預覽之後,添加一個Done按鈕來提交創建好的標籤到Complete頁面。完成之後,頁面如下:

...

Preview your customized tag above.

If you re happywiththe results,

click the button below to finish!

class="btn btn-success btn-lg"

*ngIf="petTag.shape"

[disabled]="!done"

(click)="submit()"

routerLink="/complete">Done

我們之前在CreateComponent的tagStateSubscription對象中定義了done屬性。 當done屬性是false的時候,我們禁用提交按鈕。

this.done=!!(this.petTag.shape&&this.petTag.text);

當標籤有形狀和文字時,我們就認為該標籤已經可以提交了。如果用戶已經添加了這些,他們就可以點擊提交按鈕完成標籤的創建。同時,我們將用戶導航至Complete頁面。

「Complete」頁面組件

在設置路由的時候,我們就搭建好了Complete頁面的手腳架。當這個頁面創建好之後,頁面效果如下(前提是用戶創建了一個標籤):

「Complete」頁面組件腳本

// src/app/pages/complete/complete.component.ts

import{Component,OnInit,OnDestroy}from @angular/core ;

import{Observable}from rxjs/Observable ;

import{Subscription}from rxjs/Subscription ;

import{Store}from @ngrx/store ;

import{RESET}from ./../../core/pet-tag.actions ;

import{PetTag}from ./../../core/pet-tag.model ;

@Component({

selector: app-complete ,

templateUrl: ./complete.component.html

})

exportclassCompleteComponentimplementsOnInit,OnDestroy{

tagState$:Observable;

privatetagStateSubscription:Subscription;

petTag:PetTag;

constructor(privatestore:Store){

this.tagState$=store.select( petTag );

}

ngOnInit(){

this.tagStateSubscription=this.tagState$.subscribe((state)=>{

this.petTag=state;

});

}

ngOnDestroy(){

this.tagStateSubscription.unsubscribe();

}

newTag(){

this.store.dispatch({

type:RESET

});

}

}

CompleteComponent組件是可路由的容器組件。需要導入OnInit, OnDestroy, Observable, Subscription以及Store管理store訂閱。同時,有個重置按鈕,用戶點擊之後可以重新創建標籤。store中的狀態也會跟著重置,所以需要導入RESET行為, PetTag數據類型以及默認初始值initialTag。

類似CreateComponent組件,我們需要創建tagState$的可觀察對象tagStateSubscription,以及局部變數petTag。同時,我們需要創建PetTag數據類型的emptyTag變數,然後將其賦值為initialTag。

在構造函數中,將tagState$設為store可觀察對象。然後在ngOnInit()函數中,訂閱這個可觀察對象,並且設置petTag屬性。在ngOnDestroy()函數中,通過退訂來銷毀訂閱。最後,newTag()函數派發RESET行為,使得應用的狀態重置,用戶可以繼續定製他們的下一個標籤了。

「Complete」頁面組件模板

CompleteComponent組件的模板代碼如下:

Congratulations!You ve completed a pet ID tagfor{{petTag.text}}.Would you like tocreate another?

Oops!You haven t customized a tag yet.Click here to create one now.

首先展示恭喜用戶成功為他們的寵物創建個性標籤的提示,名字也會從petTag狀態對象中取過來。同時,提供一個能重新創建新標籤的鏈接,點擊之後執行newTag()方法,該方法會將路由導航到創建頁面重新開始。

接著,展示帶有petTag的標籤預覽組件: 。

最後,如果用戶在沒有完成標籤的定製下手動導航到/complete頁面的話,我們就會顯示一個錯誤信息。同樣有個鏈接,可以讓用戶回到創建頁面。錯誤頁面效果如下:

至此,我們簡單的Angular + ngrx/store應用完成了。

題外話:你可能不需要ngrx/store

狀態管理庫很棒,但請你確保在正式投入實際項目前你已經讀過了這篇文章You Might Not Need Redux。

這個例子很簡單,因為我們是用ngrx/store來教學。當你想用來投入實際項目時,你需要權衡一下必要性以及它的利弊。Angular(吸納了RxJS)已經可以很方便地用service管理全局狀態。因此,小型簡單應用用局部變數就能很好地維護了。這種場景下,如果引入非必要的ngrx/store,可能會帶來困擾和麻煩。

而在管理大型複雜項目的狀態時,ngrx/store及其同類庫是非常出色的工具。希望你現在已經有能力判斷Redux和ngrx/store使用的原理。這樣你就能知道如何以及何時應該使用狀態管理庫了。

附狀態管理相關資源

附上一些學習狀態管理的好資源:

ngrx/store on GitHub

@ngrx/store in 10 minutes

Comprehensive Introduction to @ngrx/store

ng-conf: Reactive Angular 2 with ngrx - Rob Womald

Angular 2 Service Layers: Redux, RxJS and Ngrx Store - When to Use a Store and Why?

Getting Started with Redux - Dan Abramov on Egghead.io

Angular的服務和組件通信在小型應用中的數據傳遞變得相當簡單,但在複雜應用中仍是個棘手的問題。類似ngrx/store的全局store在組織狀態管理中起到了很大的輔助作用。希望你現在已經準備好用ngrx/store構建自己的Angular 應用了!

關於本文

譯者:@野草

譯文:https://github.com/fezaoduke/TranslationInstitute/blob/master/手把手教你用ngrx管理Angular狀態.md

作者:@Kim MaidaMr Raindrop

原文:https://auth0.com/blog/managing-state-in-angular-with-ngrx-store/

點擊展開全文

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 前端早讀課 的精彩文章:

手把手教你用ngrx管理Angular狀態(上)
「大產品小細節」Hick『s Law 希克法則
認識 V8 引擎
我接觸過的前端數據結構與演算法
阿里巴巴大優酷事業部前端專家

TAG:前端早讀課 |

您可能感興趣

TelephonyManager(電話管理器)
Spring Boot 基礎教程 ( 三 ) :使用 Cloud Studio 在線編寫、管理 Spring Boot 應用
AudioManager(音頻管理器)
監控管理之Spring Boot Admin使用
linux 使用supervisor管理開機啟動uwsgi
在docker for win中使用portainer管理容器
如何用 Google Tag Manager標籤管理器設置GA onclick按鈕點擊事件
管理vRealize Automation的vPostgres資料庫
《自我管理:Managing Oneself》導讀
把玩Alpine linux(二):APK包管理器
管理非凡的心智 Managing Brilliant Minds
Windows 上的 SSH?使用 PowerShell Remoting 遠程管理 Windows 伺服器
管理髮展 management development
Python框架:Django寫圖書管理系統
Kube:在VS Code中管理Helm charts
react+react-router+mobx+element打造管理後台系統
Facebook為何放棄ZooKeeper轉用自研配置管理系統?
Veritas收購雲數據管理公司fluid Operations AG
Mozilla推出兼容iOS的Face ID密碼管理器Firefox Lockbox
在 Linux 上使用 Lutries 管理你的遊戲