ä»æ¥ã¯ãå®å šã«OnPushæŠç¥ã«åºã¥ããŠäœæããããªã¢ã¯ãã£ãã¢ã³ã°ã«ã¢ããªã±ãŒã·ã§ã³ïŒ githubãªããžã㪠ïŒã詳现ã«åæããŸãã å¥ã®ã¢ããªã±ãŒã·ã§ã³ã¯ãªã¢ã¯ãã£ããã©ãŒã ã䜿çšããŸãããããã¯ãšã³ã¿ãŒãã©ã€ãºã¢ããªã±ãŒã·ã§ã³ã§ã¯éåžžã«äžè¬çã§ãã
FluxãReduxãNgRxã¯äœ¿çšãããTypescriptãAngularãRxJSã§æ¢ã«å©çšå¯èœãªæ©èœãå©çšããŸãã å®éããããã®ããŒã«ã¯ç¹å¹è¬ã§ã¯ãªããåçŽãªã¢ããªã±ãŒã·ã§ã³ã§ãäžå¿ èŠã«è€éã«ãªãå¯èœæ§ããããŸãã ç§ãã¡ã¯ãFluxã®äœè ã®1人 ãReduxã®äœè ãNgRxã®äœè ãããããã«ã€ããŠæ£çŽã«èŠåãããŠããŸãã
ãããããããã®ããŒã«ã¯ã¢ããªã±ãŒã·ã§ã³ã«éåžžã«åªããæ©èœãæäŸããŸã
- äºæž¬å¯èœãªããŒã¿ãããŒã
- èšèšã«ããOnPushããµããŒãããŸãã
- ããŒã¿ã®äžå€æ§ãèç©ãããå¯äœçšã®æ¬ åŠããã®ä»ã®æ¥œããããšã
åãç¹æ§ãååŸããããšããŸãããè€éããå¢ãããšã¯ãããŸããã
èšäºã®çµãããŸã§ã«ãããããã«ãããã¯éåžžã«ç°¡åãªã¿ã¹ã¯ã§ããAngularãšOnPushã®è©³çŽ°ãèšäºããåé€ãããšãããã€ãã®ç°¡åãªã¢ã€ãã¢ãããããŸããã
ãã®èšäºã§ã¯ãæ°ããæ®éçãªãã¿ãŒã³ã¯æäŸããŠããŸããããèªè ã«ããã®åçŽãã®ããã«ãäœããã®çç±ã§ããã«æãã€ããªãã£ãããã€ãã®ã¢ã€ãã¢ãå ±æããŠããã ãã§ãã ãŸããéçºããããœãªã¥ãŒã·ã§ã³ã¯ãFlux / Redux / NgRxãšççŸããã眮ãæãããããããšã¯ãããŸããã ãããæ¬åœã«å¿ èŠãªå Žåã¯ãæ¥ç¶ã§ããŸãã
èšäºãå¿«é©ã«èªãã«ã¯ã ã¹ããŒãããã¬ãŒã³ããŒã·ã§ã³ãããã³ã³ã³ããã³ã³ããŒãã³ããšããçšèªãç解ããããšãå¿ èŠã§ãã
ã¢ã¯ã·ã§ã³ãã©ã³
ã¢ããªã±ãŒã·ã§ã³ã®ããžãã¯ããã³è³æã®è¡šç€ºã®é åºã¯ã次ã®æé ã®åœ¢åŒã§èª¬æã§ããŸãã
- èªã¿åãïŒGETïŒãšæžã蟌ã¿ïŒPUT / POSTïŒã«å¥ã ã®ããŒã¿
- ã³ã³ããã³ã³ããŒãã³ãã«ã¹ããªãŒã ãšããŠç¶æ ãããŒããã
- OnPushã³ã³ããŒãã³ãã®éå±€ã«ç¶æ ãé åžãã
- ã³ã³ããŒãã³ãã®å€æŽã«ã€ããŠAngularã«éç¥ãã
- ã«ãã»ã«åãããããŒã¿ç·šé
OnPushãå®è£ ããã«ã¯ãAngularã§å€æŽæ€åºãå®è¡ãããã¹ãŠã®æ¹æ³ã解æããå¿ èŠããããŸãã ãã®ãããªæ¹æ³ã¯4ã€ãããªãããããã®èšäºå šäœã§ããããé 次æ€èšããŠãããŸãã
è¡ããŸãããã
èªã¿æžãçšã®ããŒã¿ãå ±æãã
éåžžãã¢ããªã±ãŒã·ã§ã³ã¯åä»ãã³ã³ãã©ã¯ãã䜿çšããŠãããã³ããšã³ããšããã¯ãšã³ãã®éã§éä¿¡ããŸãïŒããã§ãªãå Žåããªãtypescriptãå¿ èŠãªã®ã§ããïŒïŒã
æ€èšããŠãããã¢ãããžã§ã¯ãã«ã¯å®éã®ããã¯ãšã³ãã¯ãããŸããããäºåã«æºåãããèšè¿°ãã¡ã€ã«swagger.jsonãå«ãŸããŠããŸãã ããã«åºã¥ããŠãtypescriptã³ã³ãã©ã¯ãã¯sw2dtsãŠãŒãã£ãªãã£ã«ãã£ãŠçæãããŸãã
çæãããã³ã³ãã©ã¯ãã«ã¯2ã€ã®éèŠãªããããã£ããããŸãã
ãŸããèªã¿åããšæžã蟌ã¿ã¯ç°ãªãã³ã³ãã©ã¯ãã䜿çšããŠå®è¡ãããŸãã å°ããªèŠåã䜿çšããŠãæ¥å°ŸèŸãStateãã®å¥çŽãèªã¿åããæ¥å°ŸèŸãModelãã®å¥çŽãäœæããããšãåç §ããŸãã
ãã®ããã«å¥çŽãåé¢ããããšã«ãããã¢ããªã±ãŒã·ã§ã³å ã®ããŒã¿ãããŒãå ±æããŠããŸãã äžããäžã«ãèªã¿åãå°çšã®ç¶æ ãã³ã³ããŒãã³ãéå±€ãéããŠäŒæãããŸãã ããŒã¿ãå€æŽããã«ã¯ãæåã«ç¶æ ããã®ããŒã¿ãå ¥åãããŠããã¢ãã«ãäœæãããŸãããå¥ã®ãªããžã§ã¯ããšããŠååšããŸãã ç·šéã®æåŸã«ãã¢ãã«ã¯ã³ãã³ããšããŠããã¯ãšã³ãã«éä¿¡ãããŸãã
2çªç®ã®éèŠãªç¹ã¯ããã¹ãŠã®ç¶æ ãã£ãŒã«ããèªã¿åãå°çšä¿®é£Ÿåã§ããŒã¯ãããŠããããšã§ãã ãã®ãããtypescriptã¬ãã«ã§å ç«åã®ãµããŒããåããŠããŸãã ããã§ãã³ãŒãã®ç¶æ ã誀ã£ãŠå€æŽãããã[ïŒngModelïŒ]ã䜿çšããŠã³ãŒãã«ãã€ã³ããããããããšãã§ããªããªããŸããã¢ããªã±ãŒã·ã§ã³ãAOTã¢ãŒãã§ã³ã³ãã€ã«ãããšããšã©ãŒãçºçããŸãã
ã³ã³ããã³ã³ããŒãã³ãã«ã¹ããªãŒã ãšããŠç¶æ ãããŒããã
ç¶æ ãããŒãããŠåæåããã«ã¯ãéåžžã®è§åºŠãµãŒãã¹ã䜿çšããŸãã 圌ãã¯æ¬¡ã®ã·ããªãªãæ åœããŸãã
- å€å žçãªäŸã¯ãã«ãŒã¿ãŒããã³ã³ããŒãã³ãã«ãã£ãŠååŸãããidãã©ã¡ãŒã¿ãŒã䜿çšããŠãHttpClientãä»ããŠããŒãããããšã§ãã
- æ°ãããšã³ãã£ãã£ãäœæãããšãã«ç©ºã®ç¶æ ãåæåããŸãã ããšãã°ããã£ãŒã«ãã«ããã©ã«ãå€ãããå Žåãåæåããå Žåã¯ãããã¯ãšã³ãããè¿œå ã®ããŒã¿ãèŠæ±ããå¿ èŠããããŸãã
- ãŠãŒã¶ãŒãããŒã¿ãããã¯ãšã³ãã«å€æŽããæäœãå®è¡ããåŸãæ¢ã«ããŒããããç¶æ ãåèµ·åããŸãã
- ããŒã¿ã®å ±åç·šéæãªã©ãããã·ã¥éç¥ã«ããç¶æ ã®åèµ·åã ãã®å ŽåããµãŒãã¹ã¯ããŒã«ã«ç¶æ ãšããã¯ãšã³ãããååŸããç¶æ ãããŒãžããŸãã
ãã¢ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãæåã®2ã€ã®ã·ããªãªãæãå žåçãªãã®ãšèŠãªããŸãã ãŸãããããã®ã·ããªãªã¯åçŽã§ããããµãŒãã¹ãåçŽââãªã¹ããŒãã¬ã¹ãªããžã§ã¯ããšããŠå®è£ ã§ãããã®ç¹å®ã®èšäºã®äž»é¡ã§ã¯ãªãè€éãã«æ°ãåãããããšã¯ãããŸããã
ãµãŒãã¹ã®äŸã¯ã some-entity.service.tsãã¡ã€ã«ã«ãããŸãã
ã³ã³ããã³ã³ããŒãã³ãããã³ããŒãç¶æ ã§DIãä»ããŠãµãŒãã¹ãååŸããããšã¯æ®ããŸãã éåžžãããã¯æ¬¡ã®ããã«è¡ãããŸãã
route.params .pipe( pluck('id'), filter((id: any) => { return !!id; }), switchMap((id: string) => { return myFormService.get(id); }) ) .subscribe(state => { this.state = state; });
ãããããã®ã¢ãããŒãã§ã¯ã次ã®2ã€ã®åé¡ãçºçããŸãã
- äœæãããµãã¹ã¯ãªãã·ã§ã³ããæåã§ãµãã¹ã¯ãªãã·ã§ã³ã解é€ããå¿ èŠããããŸããããããªããšãã¡ã¢ãªãªãŒã¯ãçºçããŸãã
- ã³ã³ããŒãã³ããOnPushæŠç¥ã«åãæ¿ãããšãããŒã¿ã®èªã¿èŸŒã¿ã«å¯Ÿããå¿çãåæ¢ããŸãã
éåæãã€ããå©ãã«ãªããŸãã 圌ã¯Observableã«çŽæ¥è³ãåŸããå¿ èŠã«å¿ããŠç»é²ã解é€ããŸãã ãŸããéåæãã€ãã䜿çšãããšãAngularã¯Observableãæ°ããå€ãå ¬éãããã³ã«å€æŽæ€åºãèªåçã«ããªã¬ãŒããŸãã
éåæãã€ãã®äœ¿çšäŸã¯ã some-entity.componentã³ã³ããŒãã³ãã®ãã³ãã¬ãŒãã«ãããŸã ã
ã³ã³ããŒãã³ãã³ãŒãã§ã¯ãç¹°ãè¿ãããžãã¯ãã«ã¹ã¿ã RxJSãªãã¬ãŒã¿ãŒã«åé€ãã空ã®ç¶æ ãäœæããã¹ã¯ãªãããè¿œå ããããŒãžãªãã¬ãŒã¿ãŒã§äž¡æ¹ã®ç¶æ ãœãŒã¹ã1ã€ã®ã¹ããªãŒã ã«ããŒãžããç·šéçšã®ãã©ãŒã ãäœæããŸãã
this.state$ = merge( route.params.pipe( switchIfNotEmpty("id", (requestId: string) => requestService.get(requestId) ) ), route.params.pipe( switchIfEmpty("id", () => requestService.getEmptyState()) ) ).pipe( tap(state => { this.form = new SomeEntityFormGroup(state); }) );
ã³ã³ããã³ã³ããŒãã³ãã§è¡ãå¿ èŠãããã®ã¯ããã ãã§ãã ãããŠã貯éç®±ã«OnPushã³ã³ããŒãã³ãã®å€æŽæ€åºãåŒã³åºãæåã®æ¹æ³ãéåæãã€ããå ¥ããŸããã äœåºŠã圹ç«ã€ã§ãããã
OnPushã³ã³ããŒãã³ãã®éå±€ã«ç¶æ ãé åžãã
è€éãªç¶æ ã衚瀺ããå¿ èŠãããå Žåãå°ããªã³ã³ããŒãã³ãã®éå±€ãäœæããŸãããããè€éããåŠçããæ¹æ³ã§ãã
ååãšããŠãã³ã³ããŒãã³ãã¯ããŒã¿éå±€ã«é¡äŒŒããéå±€ã«åå²ãããåã³ã³ããŒãã³ãã¯å ¥åãã©ã¡ãŒã¿ãŒãä»ããŠç¬èªã®ããŒã¿ãåãåãããã³ãã¬ãŒãã«è¡šç€ºããŸãã
ãã¹ãŠã®ã³ã³ããŒãã³ããOnPushãšããŠå®è£ ããã®ã§ãå°ãè±ç·ããŠããããäœã§ããããAngularãOnPushã³ã³ããŒãã³ããšã©ã®ããã«æ©èœãããã«ã€ããŠèª¬æããŸãããã ãã®è³æãæ¢ã«ç¥ã£ãŠããå Žåã¯ãã»ã¯ã·ã§ã³ã®æåŸãŸã§èªç±ã«ã¹ã¯ããŒã«ããŠãã ããã
ã¢ããªã±ãŒã·ã§ã³ã®ã³ã³ãã€ã«äžã«ãAngularã¯ã³ã³ããŒãã³ãããšã«ç¹å¥ãªã¯ã©ã¹å€æŽæ€åºåšãçæããŸããããã¯ãã³ã³ããŒãã³ããã³ãã¬ãŒãã§äœ¿çšããããã¹ãŠã®ãã€ã³ãã£ã³ã°ããèšæ¶ãããŸãã å®è¡æã«ãäœæãããã¯ã©ã¹ã¯ãå€æŽæ€åºã«ãŒãããšã«ä¿åãããåŒã®ãã§ãã¯ãéå§ããŸãã ãã§ãã¯ã®çµæãåŒã®çµæãå€æŽãããããšã瀺ãããå ŽåãAngularã¯ã³ã³ããŒãã³ããåæç»ããŸãã
ããã©ã«ãã§ã¯ãAngularã¯ã³ã³ããŒãã³ãã«ã€ããŠäœãèªèããŠããªããããããšãã°ããªã¬ãŒãããsetTimeoutãå®äºããAJAXãªã¯ãšã¹ããªã©ãã©ã®ã³ã³ããŒãã³ãã«åœ±é¿ããããå€æã§ããŸããã ãããã£ãŠã圌ã¯ã¢ããªã±ãŒã·ã§ã³å ã®ãã¹ãŠã®ã€ãã³ãã«ã€ããŠæåéãã¢ããªã±ãŒã·ã§ã³å šäœããã§ãã¯ããããšãäœåãªããããŠããŸã-åçŽãªãŠã£ã³ããŠã¹ã¯ããŒã«ã§ããã¢ããªã±ãŒã·ã§ã³ã³ã³ããŒãã³ãã®éå±€å šäœã®å€æŽæ€åºãç¹°ãè¿ãããªã¬ãŒããŸãã
ããã¯ãããã©ãŒãã³ã¹ã®åé¡ã®æœåšçãªåå ãååšããå Žæã§ããã³ã³ããŒãã³ããã³ãã¬ãŒããè€éã«ãªãã»ã©ãå€æŽæ€åºããã°ã©ã ã®ãã§ãã¯ãé£ãããªããŸãã ãŸããã³ã³ããŒãã³ããå€æ°ããããã§ãã¯ãé »ç¹ã«å®è¡ãããå Žåãå€æŽã®æ€åºã«ã¯ããªãã®æéãããããŸãã
ã©ãããïŒ
ã³ã³ããŒãã³ããã°ããŒãã«ãšãã§ã¯ãã«äŸåããªãå ŽåïŒãšããã§ããã®æ¹æ³ã§ã³ã³ããŒãã³ããèšèšããæ¹ãè¯ãïŒãå éšç¶æ ã¯æ¬¡ã®ããã«æ±ºå®ãããŸãã
- å ¥åãã©ã¡ãŒã¿ãŒïŒ @Input ïŒ;
- ã³ã³ããŒãã³ãèªäœã§çºçããã€ãã³ãïŒ @Output ïŒã
ããã§ã¯2çªç®ã®ãã€ã³ãã延æããã³ã³ããŒãã³ãã®ç¶æ ãå ¥åãã©ã¡ãŒã¿ãŒã®ã¿ã«äŸåãããšä»®å®ããŸãã
ã³ã³ããŒãã³ãã®ãã¹ãŠã®å ¥åãã©ã¡ãŒã¿ãŒãäžå€ãªããžã§ã¯ãã§ããå Žåãã³ã³ããŒãã³ããOnPushãšããŠããŒã¯ã§ããŸãã 次ã«ãå€æŽæ€åºãå®è¡ããåã«ãAngularã¯ååã®ãã§ãã¯ä»¥éã«ã³ã³ããŒãã³ãã®å ¥åãã©ã¡ãŒã¿ãŒãžã®ãªã³ã¯ãå€æŽããããã©ããããã§ãã¯ããŸãã ãããŠãããããå€æŽãããŠããªãå ŽåãAngularã¯ã³ã³ããŒãã³ãèªäœãšãã®ãã¹ãŠã®åã³ã³ããŒãã³ãã®å€æŽæ€åºãã¹ãããããŸãã
ãããã£ãŠãOnPushæŠç¥ã«åŸã£ãŠã¢ããªã±ãŒã·ã§ã³å šäœãæ§ç¯ããå Žåãããã©ãŒãã³ã¹ã®åé¡ã®ã¯ã©ã¹å šäœãæåããæé€ããŸãã
ã¢ããªã±ãŒã·ã§ã³ã®Stateã¯ãã§ã«äžå€ã§ãããããäžå€ãªããžã§ã¯ãã¯åã³ã³ããŒãã³ãã®å ¥åãã©ã¡ãŒã¿ãŒã«ã転éãããŸãã ã€ãŸããåã³ã³ããŒãã³ãã«å¯ŸããŠOnPushãæå¹ã«ããæºåãã§ããŠãããåã³ã³ããŒãã³ãã¯ç¶æ ã®å€åã«å¯Ÿå¿ããŸãã
ããšãã°ããããã¯readonly-info.componentããã³nested-items.componentã³ã³ããŒãã³ãã§ã
次ã«ãOnPushãã©ãã€ã ã§ã³ã³ããŒãã³ãã®ç¶æ ã®å€æŽãå®è£ ããæ¹æ³ãèŠãŠã¿ãŸãããã
ããªãã®ç¶æ ã«ã€ããŠAngularã«çžè«ããŠãã ãã
ãã¬ãŒã³ããŒã·ã§ã³ç¶æ -ãããã¯ãã³ã³ããŒãã³ãã®å€èŠ³ã«é¢äžãããã©ã¡ãŒã¿ãŒã§ããããŒãã€ã³ãžã±ãŒã¿ãŒãèŠçŽ ã®å¯èŠæ§ã®ãã©ã°ããŸãã¯1ã€ãŸãã¯å¥ã®ã¢ã¯ã·ã§ã³ã®ãŠãŒã¶ãŒãžã®ã¢ã¯ã»ã¹å¯èœæ§ã3ã€ã®ãã£ãŒã«ããã1è¡ã«æ¥çããŠãŒã¶ãŒã®ãã«ããŒã ãªã©ã
ã³ã³ããŒãã³ãã®è¡šç€ºç¶æ ãå€æŽããããã³ã«ãAngularã«éç¥ããŠãUIã«å€æŽã衚瀺ã§ããããã«ããå¿ èŠããããŸãã
ã³ã³ããŒãã³ãã®ç¶æ ã®ãœãŒã¹ã«å¿ããŠãAngularã«éç¥ããæ¹æ³ãããã€ããããŸãã
å ¥åãã©ã¡ãŒã¿ãŒã«åºã¥ããŠèšç®ããããã¬ãŒã³ããŒã·ã§ã³ç¶æ
ãããæãç°¡åãªãªãã·ã§ã³ã§ãã ãã¬ãŒã³ããŒã·ã§ã³ç¶æ ã®èšç®ããžãã¯ãngOnChangesããã¯ã«é 眮ããŸãã @å ¥åãã©ã¡ãŒã¿ãŒãå€æŽãããšãå€æŽæ€åºãèªåçã«éå§ãããŸãã ãã¢ã§ã¯ãããã¯readonly-info.componentã§ãã
export class ReadOnlyInfoComponent implements OnChanges { @Input() public state: Backend.SomeEntityState; public traits: ReadonlyInfoTraits; public ngOnChanges(changes: { state: SimpleChange }): void { this.traits = new ReadonlyInfoTraits(changes.state.currentValue); } }
ãã¹ãŠãéåžžã«åçŽã§ããã泚æãã¹ãç¹ã1ã€ãããŸãã
ã³ã³ããŒãã³ãã®è¡šç€ºç¶æ ãè€éãªå Žåãç¹ã«äžéšã®ãã£ãŒã«ããä»ã®ãã£ãŒã«ãã«åºã¥ããŠèšç®ãããå ¥åãã©ã¡ãŒã¿ãŒã«ãã£ãŠãèšç®ãããå Žåãã³ã³ããŒãã³ãã®ç¶æ ãå¥ã®ã¯ã©ã¹ã«å ¥ããäžå€ã«ããèµ·åãããã³ã«ngOnChangesãåäœæããŸãã ãã¢ãããžã§ã¯ãã®äŸã¯ã ReadonlyInfoComponentTraitsã¯ã©ã¹ã§ãã ãã®ã¢ãããŒãã䜿çšãããšãäŸåããŒã¿ãå€æŽããããšãã«åæããå¿ èŠæ§ãã身ãå®ãããšãã§ããŸãã
åæã«ãæ€èšãã䟡å€ããããŸãããããããã³ã³ããŒãã³ãã«å«ãŸããããžãã¯ãå€ãããããã«ãã³ã³ããŒãã³ãã®ç¶æ ãé£ããå¯èœæ§ããããŸãã å žåçãªäŸã¯ã1ã€ã®ã³ã³ããŒãã³ãã§ãã·ã¹ãã ã®æäœæ¹æ³ãéåžžã«ç°ãªãããŸããŸãªãŠãŒã¶ãŒã®è¡šçŸãé©åãããè©Šã¿ã§ãã
ã³ã³ããŒãã³ããã€ãã£ãã€ãã³ã
ã¢ããªã±ãŒã·ã§ã³ã³ã³ããŒãã³ãéã®éä¿¡ã«ã¯ãåºåã€ãã³ãã䜿çšããŸãã ããã¯ãå€æŽæ€åºãå®è¡ãã3çªç®ã®æ¹æ³ã§ããããŸãã Angularã¯ãã³ã³ããŒãã³ããã€ãã³ããçæããå Žåããã®ç¶æ ãå€åããå¯èœæ§ããããšåççã«æ³å®ããŠããŸãã ãããã£ãŠãAngularã¯ãã¹ãŠã®ã³ã³ããŒãã³ãåºåã€ãã³ãããªãã¹ã³ããçºçæã«å€æŽæ€åºãããªã¬ãŒããŸãã
ãã¢ãããžã§ã¯ãã§ã¯ãå®å šã«åæãããŠããŸããããŸã äŸã¯formSavedã€ãã³ããã¹ããŒããã³ã³ããŒãã³ãsubmit-button.componentã§ãã ã³ã³ããã³ã³ããŒãã³ãã¯ãã®ã€ãã³ãããµãã¹ã¯ã©ã€ãããéç¥ãšãšãã«ã¢ã©ãŒãã衚瀺ããŸãã
åºåã€ãã³ãã¯ãæå³ããç®çã§äœ¿çšããŸããã€ãŸããå€æŽæ€åºãããªã¬ãŒããããã§ã¯ãªãã芪ã³ã³ããŒãã³ããšã®éä¿¡çšã«äœæããŸãã ããã§ãªããã°ãäœã¶æãäœå¹Žããã£ãŠããããã®ã€ãã³ããããã®èª°ã«ãšã£ãŠãäžå¿ èŠãªã®ããèŠããŠãããããããåé€ããŠããã¹ãŠãå£ãå¯èœæ§ããããŸãã
ã¹ããŒãã³ã³ããŒãã³ãã®å€æŽ
ã³ã³ããŒãã³ãã®ç¶æ ã¯ãéåæãµãŒãã¹åŒã³åºããWebãœã±ãããžã®æ¥ç¶ãsetIntervalãä»ããå®è¡ãã§ãã¯ãªã©ãè€éãªããžãã¯ã«ãã£ãŠæ±ºå®ãããå ŽåããããŸããããã以å€ã®ããšã¯ããããŸããã ãã®ãããªã³ã³ããŒãã³ãã¯ãã¹ããŒãã³ã³ããŒãã³ããšåŒã°ããŸãã
äžè¬ã«ãã³ã³ããã³ã³ããŒãã³ãã§ã¯ãªãã¢ããªã±ãŒã·ã§ã³ã®ã¹ããŒãã³ã³ããŒãã³ããå°ãªãã»ã©ãç°¡åã«äœ¿çšã§ããŸãã ããããæã«ã¯ããªãã¯ããããªãã§ã¯ã§ããŸããã
ã¹ããŒãã³ã³ããŒãã³ãã®ç¶æ ãå€æŽæ€åºã«é¢é£ä»ããæãç°¡åãªæ¹æ³ã¯ããã®ã³ã³ããŒãã³ããObservableã«å€æããæ¢ã«èª¬æããéåæãã€ãã䜿çšããããšã§ãã ããšãã°ãå€æŽã®ãœãŒã¹ããµãŒãã¹ã³ãŒã«ãŸãã¯ãªã¢ã¯ãã£ããã©ãŒã ã¹ããŒã¿ã¹ã§ããå Žåãããã¯æ¢è£œã®Observableã§ãã ç¶æ ãããè€éãªãã®ãã圢æãããŠããå Žåã fromPromise ã websocket ã timer ãRxJSã®æ§æããã®ééã䜿çšã§ããŸãã ãŸãã¯ã Subjectã䜿çšããŠèªåã§ã¹ããªãŒã ãçæããŸãã
é©åãªãªãã·ã§ã³ããªãå Žå
ãã§ã«ç 究ãããŠãã3ã€ã®æ¹æ³ã®ããããé©åã§ãªãå Žåã§ãã ChangeDetectorRefãçŽæ¥äœ¿çšããé²åŒŸãªãã·ã§ã³ããããŸãã ãã®ã¯ã©ã¹ã®detectChangesããã³markForCheckã¡ãœããã«ã€ããŠèª¬æããŠããŸãã
å æ¬çãªããã¥ã¡ã³ãããã¹ãŠã®è³ªåã«çããŠããããããã®äœæ¥ã«ã€ããŠã¯è©³ãã説æããŸããã ãã ãã ChangeDetectorRefã®äœ¿çšã¯ãAngularã®å éšãããã³ã§ãããããèªåãäœãããŠããããæ確ã«ç解ããŠããå Žåã«éå®ããå¿ èŠããããŸãã
åžžã«ããã®æ¹æ³ãå¿ èŠã«ãªãå¯èœæ§ã®ããããã€ãã®ã±ãŒã¹ãèŠã€ããŸããã
- å€æŽæ€åºã«ããæåäœæ¥-äœã¬ãã«ã³ã³ããŒãã³ãã®å®è£ ã§äœ¿çšããããèªåãäœãããŠããã®ããæ確ã«ç解ããŠãããå Žåã«ã®ã¿åœãŠã¯ãŸããŸãã
- ã³ã³ããŒãã³ãéã®è€éãªé¢ä¿-ããšãã°ããã³ãã¬ãŒãå ã®ã³ã³ããŒãã³ããžã®ãªã³ã¯ãäœæããããããã©ã¡ãŒã¿ãŒãšããŠéå±€ãŸãã¯å¥ã®ã³ã³ããŒãã³ãéå±€ãã©ã³ãã®äžäœã«ããå¥ã®ã³ã³ããŒãã³ãã«æž¡ãå¿ èŠãããå Žåã è€éã«èãããŸããïŒ ããã§ãã ãããŠãå€æŽãæ€åºããã ãã§ãªãçã¿ãããããã®ã§ããã®ãããªã³ãŒãããªãã¡ã¯ã¿ãªã³ã°ããæ¹ãè¯ãã§ãã
- Angularèªäœã®åäœã®è©³çŽ°-ããšãã°ãã«ã¹ã¿ã ControlValueAccessorãå®è£ ããå ŽåãAngularã«ãã£ãŠå¶åŸ¡å€ãéåæçã«å€æŽãã ãå€æŽãç®çã®å€æŽæ€åºãµã€ã¯ã«ã«é©çšãããªãããšããããŸãã
ãã¢ã¢ããªã±ãŒã·ã§ã³ã§ã®äœ¿çšäŸãšããŠãæåŸã®æ®µèœã§èª¬æããåé¡ã解決ããåºæ¬ã¯ã©ã¹OnPushControlValueAccessorããããŸãã ãŸãããããžã§ã¯ãã«ã¯ããã®ã¯ã©ã¹ã®ç¶æ¿è -custom radio-button.componentããããŸãã
ããã§ã3çš®é¡ãã¹ãŠã®ã³ã³ããŒãã³ãïŒã³ã³ãããã¹ããŒãããã¬ãŒã³ããŒã·ã§ã³ïŒã«å¯ŸããŠå€æŽæ€åºãšOnPushå®è£ ãªãã·ã§ã³ãå®è¡ãã4ã€ã®æ¹æ³ãã¹ãŠã«ã€ããŠèª¬æããŸããã æçµæ®µéã«é²ã¿ãŸã-ãªã¢ã¯ãã£ããã©ãŒã ã§ããŒã¿ãç·šéããŸãã
ã«ãã»ã«åãããããŒã¿ç·šé
ãªã¢ã¯ãã£ããã©ãŒã ã«ã¯ããã€ãã®å¶éããããŸãããããã¯Angularãšã³ã·ã¹ãã ã§èµ·ãã£ãæé«ã®ããšã®1ã€ã§ãã
ãŸã第äžã«ããããã¯ç¶æ ãšããŸãæ©èœããããšãã«ãã»ã«åããäºåŸå¯Ÿå¿çã«å€åã«å¯Ÿå¿ããããã«å¿ èŠãªãã¹ãŠã®ããŒã«ãæäŸããŸãã
å®éããªã¢ã¯ãã£ããã©ãŒã ã¯ãç¶æ ã«é¢ããäœæ¥ãã«ãã»ã«åããäžçš®ã®ããã¹ãã¢ã§ããããŒã¿ãšã¹ããŒã¿ã¹ã¯ç¡å¹/æå¹/ä¿çäžã§ãã
ãã®ã«ãã»ã«åãå¯èœãªéããµããŒããããã¬ãŒã³ããŒã·ã§ã³ããžãã¯ãšãã©ãŒã ã®ããžãã¯ãæ··åšãããªãããã«ããããšãæ®ããŸãã
ãã¢ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãæ€èšŒãåFormGroupã®äœæãå ¥åãã£ãŒã«ãã®ç¡å¹åç¶æ ã§ã®äœæ¥ãªã©ãäœæ¥ã®è©³çŽ°ãã«ãã»ã«åãããã©ãŒã ã®åã ã®ã¯ã©ã¹ãèŠãããšãã§ããŸãã
ç¶æ ãããŒãããããšãã«ã³ã³ããã³ã³ããŒãã³ãã«ã«ãŒããã©ãŒã ãäœæããç¶æ ããªããŒããããã³ã«ãã©ãŒã ãåäœæãããŸãã ããã¯åææ¡ä»¶ã§ã¯ãããŸãããããã©ãŒã ããžãã¯ã«ä»¥åã®ããŒãç¶æ ããæ®ã£ã环ç©å¹æããªãããšã確èªã§ããŸãã
ãã©ãŒã èªäœã®å éšã§ãã³ã³ãããŒã«ãæ§ç¯ããã³ã³ãããŒã«ããã®ããŒã¿ãã移åãããããããStateã³ã³ãã©ã¯ãããModelã³ã³ãã©ã¯ãã«å€æããŸãã ãã©ãŒã ã®æ§é ã¯ãå¯èœãªéããã¢ãã«ã®å¥çŽãšäžèŽããŸãã ãã®çµæããã©ãŒã ã®valueããããã£ã¯ãããã¯ãšã³ãã«éä¿¡ããããã®æ¢è£œã®ã¢ãã«ãæäŸããŸãã
å°æ¥ãç¶æ ãŸãã¯ã¢ãã«æ§é ãå€æŽãããå Žåããã£ãŒã«ããè¿œå /åé€ããå¿ èŠãããå Žæã§ã¿ã€ãã¹ã¯ãªããã®ã³ã³ãã€ã«ãšã©ãŒãçºçããŸããããã¯éåžžã«äŸ¿å©ã§ãã
ãŸããç¶æ ãªããžã§ã¯ããšã¢ãã«ãªããžã§ã¯ãã®æ§é ãå®å šã«åäžã§ããå Žåãtypescriptã§äœ¿çšãããæ§é ã¿ã€ãã³ã°ã«ãããçžäºã®ç¡æå³ãªãããã³ã°ãæ§ç¯ããå¿ èŠããªããªããŸãã
å šäœãšããŠããã©ãŒã ããžãã¯ã¯ã³ã³ããŒãã³ãå ã®ãã¬ãŒã³ããŒã·ã§ã³ããžãã¯ããåé¢ãããã¢ããªã±ãŒã·ã§ã³å šäœã®ããŒã¿ãããŒã®è€éããå¢ãããšãªããåç¬ã§ãåç¶ããŸãã
ãããã»ãšãã©ãã¹ãŠã§ãã ãã©ãŒã ããžãã¯ãã¢ããªã±ãŒã·ã§ã³ã®æ®ãã®éšåããåé¢ã§ããªãå Žåã®å¢çã±ãŒã¹ãæ®ã£ãŠããŸãã
- å ¥åãããå€ã«å¿ããããŒã¿ãããã¯ã®å¯èŠæ§ãªã©ã衚瀺ç¶æ ã®å€æŽã«ã€ãªãããã©ãŒã ã®å€æŽã ãã©ãŒã ã€ãã³ãã«ãµãã¹ã¯ã©ã€ãããããšã«ãããã³ã³ããŒãã³ãã«å®è£ ããŸãã ããã¯ãåè¿°ã®äžå€ã®ç¹æ§ãä»ããŠè¡ãããšãã§ããŸãã
- ããã¯ãšã³ããåŒã³åºãéåæããªããŒã¿ãŒãå¿ èŠãªå Žåã¯ãã³ã³ããŒãã³ãã§AsyncValidatorFnãæ§ç¯ãããµãŒãã¹ã§ã¯ãªããã©ãŒã ã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ããŸãã
ãããã£ãŠããã¹ãŠã®ãå¢çç·ãããžãã¯ã¯ãã³ã³ããŒãã³ãå ã®æãé¡èãªå Žæã«æ®ããŸãã
çµè«
ç§ãã¡ãåŸããã®ãšãç 究ãšéçºã®ããã®ä»ã®ãã€ã³ãããŸãšããŸãããã
ãŸããOnPushæŠç¥ã®éçºã«ãããã¢ããªã±ãŒã·ã§ã³ã®ããŒã¿ãããŒãæ éã«èšèšããå¿ èŠããããŸããããã¯ãã²ãŒã ã®ã«ãŒã«ã圌ã§ã¯ãªãAngularã«æ瀺ããŠããããã§ãã
ãã®ç¶æ³ã«ã¯2ã€ã®çµæããããŸãã
ãŸããã¢ããªã±ãŒã·ã§ã³ãå¿«é©ã«ã³ã³ãããŒã«ã§ãããšããæèŠãåŸãããŸãã ãäœããã®åœ¢ã§æ©èœãããéæ³ã¯ãã¯ããããŸããã ã¢ããªã±ãŒã·ã§ã³å ã®ä»»æã®æç¹ã§äœãèµ·ãã£ãŠããããæ確ã«èªèããŠããŸãã çŽèŠ³ã¯åŸã ã«éçºãããŠãããã³ãŒããéãåã§ãã£ãŠããèŠã€ãã£ããã°ã®çç±ãç解ã§ããŸãã
第äºã«ãã¢ããªã±ãŒã·ã§ã³ã®èšèšã«ããå€ãã®æéãè²»ããå¿ èŠããããŸãããçµæã¯åžžã«æããçŽæ¥çãã§ããããããã£ãŠæãåçŽãªãœãªã¥ãŒã·ã§ã³ã«ãªããŸãã ããã«ãããã¢ããªã±ãŒã·ã§ã³ã倧ãããªãã«ã€ããŠéåžžã«è€éãªã¢ã³ã¹ã¿ãŒã«ãªããéçºè ããã®è€éãã®å¶åŸ¡ã倱ããéçºãç¥ç§çãªååŒã«äŒŒãç¶æ³ã«ãªãå¯èœæ§ãèãããŒãã«ãªããŸãã
å¶åŸ¡ãããè€éããšãéæ³ãã®æ¬ åŠã«ãããããšãã°åšæçãªããŒã¿æŽæ°ãèç©ãããå¯äœçšãªã©ããçºçããåé¡å šäœã®å¯èœæ§ãæžå°ããŸãã 代ããã«ãã¢ããªã±ãŒã·ã§ã³ãåã«æ©èœããªãå Žåã«ãéçºäžã«ãã§ã«ç®ç«ã€åé¡ã«å¯ŸåŠããŠããŸãã ãŸããã¢ããªã±ãŒã·ã§ã³ãåçŽãã€æ確ã«æ©èœãããå¿ èŠããããŸãã
ãŸããããã©ãŒãã³ã¹ãžã®è¯ã圱é¿ã«ã€ããŠãèšåããŸããã ä»ã profiler.timeChangeDetectionãªã©ã®éåžžã«åçŽãªããŒã«ã䜿çšããŠããã€ã§ãã¢ããªã±ãŒã·ã§ã³ãè¯å¥œãªç¶æ ã§ããããšã確èªã§ããŸãã
ãŸããä»ã§ã¯NgZoneãç¡å¹ã«ããããšããªãããšã¯çœªã§ã ã ãŸããããã«ãããã¢ããªã±ãŒã·ã§ã³ã®èµ·åæã«ã©ã€ãã©ãªå šäœãããŒãããªãããã«ã§ããŸãã 次ã«ãã¢ããªã±ãŒã·ã§ã³ããããªãã®éã®éæ³ãåãé€ããŸãã
ãããã¹ããŒãªãŒã®çµããã§ãã
ç§ãã¡ã¯é£çµ¡ããŸãïŒ