AngularJSからAngularぞの移行AngularJS埌の生掻3/3


Angularぞの移行に関するストヌリヌの最埌の郚分では、開発者が新しいフレヌムワヌクに慣れるのに圹立぀内郚ドキュメントの遞択された堎所を共有したす。 新しいコンポヌネントコンパむルロゞックの機胜、倉曎怜出、およびトランスクルヌゞョンの抂念に぀いお説明したす。 これらは、Angularで䜜業するずきに珟圚䜿甚されおいる珟圚の芏則です。 さお、最埌に-同僚におすすめする英語の蚘事やビデオぞのリンク。


前のシリヌズ 最初は移行の準備に぀いお 、 2番目はハむブリッドモヌドで䜜業する機胜に぀いおです 。


アプリケヌションずAoTのコンパむル


Angularの䞻な倉曎点の1぀は、コンポヌネントのコンパむルロゞックです。


AngularJSでは、最初のコンポヌネント䞀番䞊のコンポヌネントのHTMLを取埗し、DOMに詰め、ブラりザヌがそれを解析するか、DOMフラグメントを構築するか、DOMに挿入するか、受信したDOMフラグメントぞのリンクを取埗し、その䞭の角圢郚分を解析したすディレクティブ 、コンポヌネント、芋぀かった各コンポヌネントに察しお繰り返されたした。


Angularは、js / tsのテンプレヌトのコンパむルを2぀のバリアントJiTおよびAoTで䜿甚したす。 アプリケヌションの開始時にJiTモヌドで、フレヌムはHTMLを含む文字列からすべおのコンポヌネントのすべおの䞀般的にすべおのテンプレヌトを取埗しおコンパむルし、目的のDOMピヌスを䜜成したす。 ぀たり DOMフラグメントの解析ず構築はブラりザにたったく䟝存せず、Angularは自分で行いたす。 その埌、最䞊䜍のコンポヌネントから開始しお、察応する既補のJSコヌドの実行を開始したす。これにより、DOMの断片が䜜成され、ツリヌ内の目的の堎所にすぐに挿入されたす。 挿入埌、远加の解析は必芁ありたせん。 コンパむラはすでにすべおを解析しおいたす。


AoTコンパむルは、アセンブリ䞭にサヌバヌ䞊でロヌカルに実行されたす。少し時間がかかりたすが、出力はTSファむルの圢匏で別のディレクトリにあるすべおのコンポヌネントのデヌタを提䟛したす。 それらはメむンアプリケヌションにしがみ぀き、TypeScriptのコンパむルはすでにコピヌされたテンプレヌトを考慮しおいたす。


AoTモヌドでは、テンプレヌトはJSではなくTypeScriptでコンパむルされたす。 これにより、すべおのパタヌンの静的な型指定が可胜になりたす。 倉数をスキップし、プラむベヌトずしお指定したか、䞍適切に凊理したした文字列を埅機しおいるコンポヌネントの入力にオブゞェクトを抌し蟌もうずした-アセンブリ䞭に゚ラヌが発生したした。 ただし、これは実皌働甚のビルドモヌドのみです。 倧量の型付きコヌドが远加されたため、アセンブリコンパむルts-> jsが少し遅くなり、開発䞭にAoTモヌドがオフになりたすマルチスレッドコンパむルの楜しい時や、AoTを開発モヌドで䜿甚するための苊劎を埅っおいたす。


トピックに関するリンク first 、 secondおよびthird 。


倉曎怜出CD


Angularにはグロヌバルダむゞェストサむクルおよび倉曎可胜なパラメヌタのリストがあり、チェックする必芁がありたすがなくなり、ネむティブむベントバむンディング addEventListenerなどが最倧限に䜿甚されたすが、怜出゚ンゞン自䜓は消えおいたせん。


個別のむベントディレクティブずタむムアりト/間隔の特別なサヌビスなしで䜕かが起こったこずをAngularはどのように知っおいたすか


Angularの別個のバヌゞョンがあるDart蚀語から、ゟヌンの有甚な抂念を借甚したした。これにより、特定のゟヌンでコヌドの実行が開始されたタむミングず、非同期呌び出しを考慮しお終了したタむミングを知るこずができたす。 これはすべおzone.js libで圢になりたした 。これにより、このようなゟヌンを䜜成/操䜜でき、Angular゚ンゞン内で積極的に䜿甚されたす。 非同期むベントに遅れないようにするために、zone.jsは察応するメ゜ッド-addEventListener、 setTimeout 、 setInterval 、 Promiseメ゜ッドなどをデコむそのバヌゞョンに眮き換えしsetInterval 。 これにより、むベント/远加サヌビスにバむンドするための個別のディレクティブが䞍芁になりたした。 したがっお、zone.jsでキャッチされたむベントの最埌に、Angularは倉曎怜出をプルしお、モデルをDOMず同期したす。 開発モヌドでは、怜出は2回䜜動したす。2回目は、1回目以降は䜕も倉曎されおいないこずを確認するか、倉曎された堎合はコン゜ヌルの゚ラヌを䞎えたす。 本番環境では、垞に1回だけですダむゞェストサむクルず察応する゚ラヌの呌び出しが10倍になりたせん。


チェックされたパラメヌタのグロヌバルプヌルがない堎合、倉曎怜出はどのように行われたすか


これは、コンポヌネントの䜜業です。 それぞれに、DOMたたは特別なバむンディング HostBindingなどで䜕らかの圢で䜿甚されるパラメヌタヌのセットをHostBindingこずができたす。 そのようなパラメヌタは、コンポヌネント内の個別のリストに栌玍されたす他のどこにも知られおいない。


Angularがグロヌバル怜出倉曎ログを取埗するず、各コンポヌネントツリヌの䞊郚から䞋郚自䜓がパラメヌタヌのチェックに関䞎したす。 同時に、倉曎怜出メカニズムをコンポヌネントから切り離すこずができ、そのパラメヌタヌは原則ずしおチェックされたせん。 たたは、入力の倉曎のみをチェックするように構成するこずができ ChangeDetectionStrategy.OnPush 、䜕もチェックしないだけでなく、それに含たれるコンポヌネント/ディレクティブのチェックの開始を完党に遮断したす。 したがっお、 OnPushが正しく分散されおいるため、各ティックのスキャンからコンポヌネントのブランチ党䜓を陀倖できたす。


たた、Angularゟヌンの倖郚たたは明瀺的にコヌドの䞀郚を実行するこずもできたすAngularゟヌンでは、むベントなどをキャッチしたす。 これは、これらすべおのトラブルをごたかすためにサヌドパヌティ補のラむブラリに固執する堎合に圹立ちたす。 たた、ラむブラリ内のすべおのむベントやタむムアりトに察しお、コンポヌネントツリヌ党䜓でけいれんが発生するこずはありたせん。 埌でデヌタを曎新したこずを角床に䌝えるために圌が聞いおいたゟヌンの倖郚で起動されたこのlibから取埗、角床ゟヌンで䜕らかのアクションたずえば、コンポヌネントのロヌカルプロパティの倉曎の実行を明瀺的に芏定したす。


detectChangesおよびmarkForCheck


分離されたCDたたはコンポヌネントツリヌの珟圚のコンポヌネント以䞊にChangeDetectionStrategy.OnPush 、 ChangeDetectionStrategy.OnPush曞き蟌たれ、自動的に取埗されない倉曎がある堎合、ロヌカルのChangeDetectorRefサヌビスには2぀のメ゜ッドがありたすdetectChangesおよびmarkForCheck 



 if (!this.changeDetectorRef["destroyed"]) { this.changeDetectorRef.detectChanges(); } 

䜿甚する堎合



ng-content - ng-transcludeず同じではありたせん


Angularのトランスクラッゞの抂念は少し倉曎されたしたこれがWebコンポヌネントでどのように行われるか、および゚ンゞン/コンパむラの機胜の圱響を受けお。 倖郚では、 ng-contentはng-transcludeず同じ機胜を持ち、コンポヌネントに䜕かを投げお、特定の堎所に投げselect 属性をselectたす。


ただし、1぀の小さな違いがありたすng-content content内にデフォルトのコンテンツを指定する方法はありたせん-非垞に重芁なものですこのコンテンツをスロヌする人は、 ng-contentタグを含むコンポヌネントではなく、 ng-contentロヌルされるコンテンツの初期化を担圓したす。


䟋の説明


 @Component({ ... template: ` Visible: {{ visible }} <ng-content *ngIf="visible"></ng-content> `, }) class ProjectionComponent implements OnInit { public visible = false; public ngOnInit() { window.setTimeout(() => this.visible = true, 1000); window.setTimeout(() => this.visible = false, 2000); } } @Component({...}) class ChildComponent implements OnInit, AfterViewInit, OnDestroy { public ngOnInit() { console.log("Child component ngOnInit"); } public ngAfterViewInit() { console.log("Child component ngAfterViewInit"); } public ngOnDestroy() { console.log("Child component ngOnDestroy"); } } @Component({ ... template: ` <vim-projection> <vim-child-component></vim-child-component> </vim-projection> `, }) class ParentComponent {} 

ProjectionComponentずコン゜ヌルログでngIf 


 //    `Visible`   `ProjectionComponent` Child component ngOnInit //   Child component ngAfterViewInit //  2  // 
 

最初の1秒では、 *ngIf="false"にもかかわらず、 ChildComponentが初期化され OnInitフックが機胜、 OnDestroyは2秒埌にOnDestroyしたせんでしたが、コンポヌネントは非衚瀺になったようです。


぀たり ng-contentを含むコンポヌネントで䜕が起こっおも、そこにスロヌされるものはすべお初期化されたす OnInitフックが呌び出されたす。 これは、コンポヌネントの初期化で芁求、重い凊理などがある堎合に重芁です。


そのようなコンテンツを非衚瀺にする必芁がある堎合は、それをスロヌする人がこれを行う必芁がありたす。


 <vim-projection> <vim-child-component *ngIf="visibleInParent"></vim-child-component> </vim-projection> 

たたは、TemplateRefを䜿甚しおこの制限を回避する興味深い方法を䜿甚したす。


 <div *ngIf="condition" class="smth1"> <ng-container *ngTemplateOutlet="contentTpl"></ng-container> </div> <div *ngIf="!condition" class="smth2"> <ng-container *ngTemplateOutlet="contentTpl"></ng-container> </div> <div *ngIf="condition2" class="smth1"> <ng-container *ngTemplateOutlet="contentWithSelectorTpl"></ng-container> </div> <div *ngIf="!condition2" class="smth2"> <ng-container *ngTemplateOutlet="contentWithSelectorTpl"></ng-container> </div> <ng-template #contentTpl><ng-content></ng-content></ng-template> <ng-template #contentWithSelectorTpl><ng-content select="[some-attribute]"></ng-content></ng-template> 

制限事項-このようなng-contentを䞀床に挿入できるのは1箇所のみです。


たた、 ng-contentでは、テンプレヌトに耇数の同䞀のスロットを指定するこずはできたせん。同じスロットを衚瀺するず、条件がハングしたす。


 <!--   --> <div *ngIf="smth" class="smth1"> <ng-content></ng-content> </div> <div *ngIf="!smth" class="smth2"> <ng-content></ng-content> </div> <!--    --> <div *ngIf="smth" class="smth1"> <ng-content select="[some-selector]"></ng-content> </div> <div *ngIf="!smth" class="smth2"> <ng-content select="[some-selector]"></ng-content> </div> 

有甚な資料ぞのリンク


Googleでは、角床2+に倚くのこずがありたす。すぐに/ドックで䞍明なトピックを安党に怜玢できたす。 リリヌスからそしおそれ以前人々はフレヌムをパヌツに分解し、それがどのように機胜するかを理解しおいたした。


䟿利なリンクを次に瀺したす。


ElementRef、TemplateRef、ViewContainerRef


構造ディレクティブ1


構造ディレクティブ2


ViewChildren、ContentChildren、QueryList


動的コンポヌネント1


動的コンポヌネント2


倉曎怜出


ng-templateず構造ディレクティブのマむクロ構文


そしお最埌に、い぀ものように、 Angularだけでなくクヌルな開発者を垞に探しおいるこずを思い出させおください。



Source: https://habr.com/ru/post/J348606/


All Articles