手把手教你用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 管理你的遊戲