NGRXActios
Actios/reducerutilityforNGRX.ItprovidesahadfuloffuctiostomakeNGRX/ReduxmoreAgular-tastic.
@Store(MyIitialState):Decoratorfordefaultstateofastore.@Actio(...MyActioClass:Actio[]):Decoratorforaactiofuctio.@Effect(...MyActioClass:Actio[]):Decoratorforaeffectfuctio.ofActio(MyActioClass):LettableoperatorforNGRXEffectscreateReducer(MyStoreClass):Reducerbootstrapfuctio@Select('my.prop'):SelectdecoratorIspiredbyredux-actadredux-actiosforRedux.
Seechagelogforlatestchages.
NOTE:IrecommedcheckigoutmylatestlibrarycalledNGXS.
Whatsthisfor?ThisissugartohelpreduceboilerplatewheusigReduxpatters.Thatsaid,here'sthehighlevelofwhatitprovides:
ReducersbecomeclassessoitsmorelogicalorgaizatioAutomaticallycreatesewistacessoyoudo'thavetohadlespreadseverywhereEablesbettertypecheckigisideyouractiosReduceshavigtopasstypecostatsbyusigtypecheckigItsdeadsimple(<100LOC)adyoucapickadchoosewhereyouwattouseit.
GettigStartedTogetstarted,letsistallthepackagethrupm:
pmigrx-actios--SReducersNext,createaactiojustlikeyoudowithNGRXtoday:
exportclassMyActio{readolytype='MyActio';costructor(publicpayload:MyObj){}}theyoucreateaclassaddecorateitwithaStoredecoratorthatcotaistheiitialstateforyourreducer.WithithatclassyoudefiemethodsdecoratedwiththeActiodecoratorwithaargumetoftheactioclassyouwattomatchito.
import{Store,Actio}from'grx-actios';@Store({collectio:[],selectios:[],loadig:false})exportclassMyStore{@Actio(Load,Refresh)load(state:MyState,actio:Load){state.loadig=true;}@Actio(LoadSuccess)loadSuccess(state:MyState,actio:LoadSuccess){state.collectio=[...actio.payload];}@Actio(Selectio)selectio(state:MyState,actio:Selectio){state.selectios=[...actio.payload];}@Actio(DeleteSuccess)deleteSuccess(state:MyState,actio:DeleteSuccess){costidx=state.collectio.fidIdex(r=>r.myId===actio.payload);if(idx===-1){returstate;}costcollectio=[...state.collectio];collectio.splice(idx,1);retur{...state,collectio};}}Youmayotice,Ido'treturthestate.Thatsbecauseifitdoes'tseeastatereturedfromtheactioitispectswhetherthestatewasaobjectorarrayadautomaticallycreatesaewistaceforyou.Ifyouaremutatigdeeplyestedproperties,youstilleedtodealwiththoseyourself.
Youcastillreturthestateyourselfaditwo'tmesswithit.Thisishelpfulforifthestatedid'tchageoryouhavesomecomplexlogicgoigo.ThiscabeseeithedeleteSuccessactio.
Aboveyoumayotice,thefirstactiohasmultipleactioclasses.Thatsbecausethe@Actiodecoratorcaacceptsigleormultipleactios.
TohookituptoNGRX,allyouhavetodoiscallthecreateReducerfuctiopassigyourstore.NowpassthemyReducerjustlikeyouwouldafuctiowithaswitchstatemetiside.
import{createReducer}from'grx-actios';exportfuctiomyReducer(state,actio){returcreateReducer(MyStore)(state,actio);}Itheaboveexample,IreturafuctiothatretursmycreateReducer.ThisisbecauseAoTcomplaisstatigFuctioexpressiosareotsupportedidecoratorsifwejustassigthecreateReducermethoddirectly.ThisisakowissueadotherNGRXthigssufferfromittoo.
Next,passthattoyourNGRXmodulejustlikeormal:
@NgModule({imports:[StoreModule.forRoot({pizza:pizzaReducer})]})exportclassAppModule{}OptioallyyoucaalsoprovideyourstoredirectlytotheNgrxActiosModuleaditwillhadlecreatigthereducerforyouadalsoeablestheabilitytouseDIwithyourstores.SoratherthadescribigiforRootorforFeaturewithStoreModule,wecallthemoNgrxActiosModule.
@NgModule({imports:[NgrxActiosModule.forRoot({pizza:PizzaStore})],providers:[PizzaStore]})exportclassAppModule{}EffectsIfyouwattouseNGRXeffects,I'vecreatedalettableoperatorthatwillallowyoutopasstheactioclassastheargumetlikethis:
import{ofActio}from'grx-actios';@Ijectable()exportclassMyEffects{costructor(privateupdate$:Actios,privatemyService:MyService){}@Effect()Load$=this.update$.pipe(ofActio(Load),switchMap(()=>this.myService.getAll()),map(res=>ewLoadSuccess(res)));}I3.x,weitroducedaewdecoratorcalled@Effectthatyoucadefieiyourstoretoperformasycoperatios.
@Store({delievered:false})exportclassPizzaStore{costructor(privatepizzaService:PizzaService){}@Actio(DeliverPizza)deliverPizza(state){state.delivered=false;}@Effect(DeliverPizza)deliverPizzaToCustomer(state,{payload}:DeliverPizza){this.pizzaService.deliver(payload);}}Effectsarealwaysruafteractios.
SelectsWedid'tleaveoutselectors,thereisaSelectdecoratorthatacceptsa(deep)pathstrig.Thislookslike:
@Compoet({...})exportclassMyCompoet{//Fuctios@Select((state)=>state.color)color$:Observable<strig>;//Arrayofprops@Select(['my','prop','color'])color$:Observable<striv>;//Deeplyestedproperties@Select('my.prop.color')color$:Observable<strig>;//Impliedbytheameofthemember@Select()color:Observable<strig>;//Remaptheslicetoaewobject@Select(state=>state.map(f=>'blue'))color$:Observable<strig>;}Thiscahelpcleaupyourstoreselects.Tohookitup,itheAppModuleyoudo:
import{NgrxActiosModule}from'grx-actios';@NgModule({imports:[NgrxActiosModule]})exportclassAppModule{}Adyoucastartusigitiaycompoet.Italsoworkswithfeaturestorestoo.Note:TheSelectdecoratorhasalimitatiooflackoftypecheckigduetoTypeScript#4881.
CommoQuestiosWhataboutcompositio?Wellsiceitcreatesaormalreducerfuctio,youcastilluseallthesamecompositiofsyoualreadyuse.WillthisworkwithormalRedux?WhileitsdesigedforAgularadNGRXitwouldworkperfectlyfieforormalRedux.Ifthatgetsrequested,I'llbehappytoaddbettersupporttoo.DoIhavetorewritemyetireapptousethis?No,youcausethisicombiatiowiththetraditioalswitchstatemetsorwhateveryouarecurretlydoig.DoesitsupportAoT?Yesbutseeaboveexamplefordetailsoimplemetatio.DoesthisworkwithNGRXDevTools?Yes,itdoes.Howdoesitworkwithtestig?Everythigshouldworkthesamewaybutdo'tforgetifyouusetheselectortooltoicludethatiyourtestruerthough.CommuityReducigBoilerplatewithNGRX-ACTIONSAdveturesiAgular:NGRXBoilerplateItroducigNGRX-Actios3.0
评论