Angular 変更検出における DOM 更新メカニズムの簡単な分析
変更検出は Angular の重要な部分であり、モデルとビュー間の同期を維持します。日々の開発プロセスでは、変更検出について知る必要はありません。Angular がこの部分の作業を完了するのに役立ち、開発者はビジネスの実装により集中できるようになり、開発効率と開発エクスペリエンスが向上します。ただし、フレームワークを詳しく使用したい場合、または単に関数を実装するのではなく高パフォーマンスのコードを作成したい場合は、変更検出について理解する必要があります。これは、フレームワークの理解を深め、エラーをデバッグし、パフォーマンスを向上させるのに役立ちます。 [関連チュートリアルの推奨事項: "angular チュートリアル "]
Angular の DOM 更新メカニズム
最初に小さな例を見てみましょう。
#ボタンをクリックすると、name 属性が変更され、DOM が新しい name 値で自動的に更新されます。
ここで質問ですが、name の値を変更して DOM に innerText を出力すると、どのような値になりますか?
import { Component, ViewChild, ElementRef } from '@angular/core'; @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: [ './app.component.css' ] }) export class AppComponent { name = 'Empty'; @ViewChild('textContainer') textContainer: ElementRef; normalClick(): void { this.name = 'Hello Angular'; console.log(this.textContainer.nativeElement.innerText); } }
正解できましたか?
では、これら 2 つのコードでは一体何が起こったのでしょうか?
ネイティブ JS を使用してこのコードを記述する場合、ボタンをクリックしてもビューは絶対に変わりませんが、Angular ではビューが変更されるのに、なぜ自動的にビューが更新されるのでしょうか? 毛糸?これはzone.jsというライブラリと切り離せないもので、簡単に言うと値が変化するイベントの処理を行うもので、これについては次のセクションで詳しく説明しますので、今はこれだけ知っていれば十分です。
このライブラリにこの処理を実行させたくない場合、Angular にはzone.js を無効にする方法も用意されています。
main.ts でzone.js を無効にすることができます。
import { enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; if (environment.production) { enableProdMode(); } platformBrowserDynamic().bootstrapModule(AppModule, { ngZone: 'noop' }) .catch(err => console.error(err));
zone.js を無効にすると、ビューは更新されません。ソース コードに移動して、ビューの更新に関連するコードを見つけます。
*/ class ApplicationRef { /** @internal */ constructor(_zone, _injector, _exceptionHandler, _initStatus) { this._zone = _zone; this._injector = _injector; this._exceptionHandler = _exceptionHandler; this._initStatus = _initStatus; /** @internal */ this._bootstrapListeners = []; this._views = []; this._runningTick = false; this._stable = true; this._destroyed = false; this._destroyListeners = []; /** * Get a list of component types registered to this application. * This list is populated even before the component is created. */ this.componentTypes = []; /** * Get a list of components registered to this application. */ this.components = []; this._onMicrotaskEmptySubscription = this._zone.onMicrotaskEmpty.subscribe({ next: () => { this._zone.run(() => { this.tick(); }); } }); ... } /** * Invoke this method to explicitly process change detection and its side-effects. * * In development mode, `tick()` also performs a second change detection cycle to ensure that no * further changes are detected. If additional changes are picked up during this second cycle, * bindings in the app have side-effects that cannot be resolved in a single change detection * pass. * In this case, Angular throws an error, since an Angular application can only have one change * detection pass during which all change detection must complete. */ tick() { NG_DEV_MODE && this.warnIfDestroyed(); if (this._runningTick) { const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) ? 'ApplicationRef.tick is called recursively' : ''; throw new RuntimeError(101 /* RuntimeErrorCode.RECURSIVE_APPLICATION_REF_TICK */, errorMessage); } try { this._runningTick = true; for (let view of this._views) { view.detectChanges(); } if (typeof ngDevMode === 'undefined' || ngDevMode) { for (let view of this._views) { view.checkNoChanges(); } } } catch (e) { // Attention: Don't rethrow as it could cancel subscriptions to Observables! this._zone.runOutsideAngular(() => this._exceptionHandler.handleError(e)); } finally { this._runningTick = false; } } }
広い解釈では、この ApplicationRef は Angular アプリケーション全体のインスタンスです。コンストラクターでは、zone (ゾーン ライブラリ) onMicrotaskEmpty (名前から察するにマイクロタスクをクリアする科目です) サブスクライブしました。サブスクリプションでは、tick() が呼び出されます。tick では何が行われるのでしょうか?
感想: 前回、コンストラクター内でサブスクライブしない方が良いと言いましたが、なぜここでこれほど不規則になるのでしょうか。
もちろんそうではありません。前回は、Angular コンポーネントのどの部分を constructor に配置する必要があり、どの部分を ngOnInit に配置する必要があるかについて説明しました。ただし、ここでは ApplicationRef はサービスであるため、初期化コードは constructor にのみ配置できます。
tick 関数では、tick 関数が実行中であることが判明した場合、これはアプリケーション全体のインスタンスであり、再帰的に呼び出すことができないため、例外がスローされます。次に、すべてのビューを走査し、各ビューで detectChanges() が実行され、変更検出が実行されます。変更検出については後で詳しく説明します。その直後、devMode の場合、すべてのビューが再度走査され、各ビューが checkNoChanges() を実行して変更があるかどうかを確認します。変更がある場合は、エラーがスローされます ( Thisこの問題については後で詳しく説明します)。ここでは をスキップしてください)。
さて、これで更新方法がわかりました。つまり、ApplicationRef の tick メソッドを呼び出すことです。
import { Component, ViewChild, ElementRef, ApplicationRef } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { name = 'Empty'; @ViewChild('textContainer') textContainer: ElementRef = {} as any; constructor(private app: ApplicationRef){} normalClick(): void { this.name = 'Hello Angular'; console.log(this.textContainer.nativeElement.innerText); this.app.tick(); } }
案の定、ビューは正常に更新できます。
簡単に整理しましょう。DOM の更新は tick() のトリガーに依存しています。zone.js は、開発者がこの操作を手動でトリガーすることを回避するのに役立ちます。さて、これでzone.jsを有効にすることができます。
それでは、変化検出とは何でしょうか?次回の記事もお楽しみに。
プログラミング関連の知識について詳しくは、プログラミング教育をご覧ください。 !
以上がAngular 変更検出における DOM 更新メカニズムの簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









ノンブロッキングおよびイベント駆動に基づいて構築されたノード サービスには、メモリ消費量が少ないという利点があり、大量のネットワーク リクエストの処理に非常に適しています。大量のリクエストを前提として、「メモリ制御」に関する問題を考慮する必要があります。 1. V8 のガベージ コレクション メカニズムとメモリ制限 Js はガベージ コレクション マシンによって制御されます

Vue.js は、今日のフロントエンド開発において非常に人気のあるフレームワークとなっています。 Vue.js が進化し続けるにつれて、単体テストの重要性がますます高まっています。今日は、Vue.js 3 で単体テストを作成する方法を検討し、いくつかのベスト プラクティスと一般的な問題と解決策を提供します。

ファイル モジュールは、ファイルの読み取り/書き込み/開く/閉じる/削除の追加など、基礎となるファイル操作をカプセル化したものです。ファイル モジュールの最大の特徴は、すべてのメソッドが **同期** と ** の 2 つのバージョンを提供することです。 asynchronous**、sync サフィックスが付いているメソッドはすべて同期メソッドであり、持たないメソッドはすべて異種メソッドです。

PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ 今日のインターネットの急速な発展の時代において、フロントエンド開発はますます重要になっています。 Web サイトやアプリケーションのエクスペリエンスに対するユーザーの要求がますます高まっているため、フロントエンド開発者は、より効率的で柔軟なツールを使用して、応答性の高いインタラクティブなインターフェイスを作成する必要があります。フロントエンド開発の分野における 2 つの重要なテクノロジーである PHP と Vue.js は、組み合わせることで完璧なツールと見なされます。この記事では、PHP と Vue の組み合わせと、読者がこれら 2 つをよりよく理解し、適用できるようにするための詳細なコード例について説明します。

クロスドメインは開発においてよく遭遇するシナリオであり、インタビューでもよく議論される問題でもあります。一般的なクロスドメイン ソリューションとその背後にある原則を習得すると、開発効率が向上するだけでなく、面接でのパフォーマンスも向上します。

フロントエンド開発のインタビューでは、HTML/CSS の基本、JavaScript の基本、フレームワークとライブラリ、プロジェクトの経験、アルゴリズムとデータ構造、パフォーマンスの最適化、クロスドメイン リクエスト、フロントエンド エンジニアリング、デザインパターン、新しいテクノロジーとトレンド。面接官の質問は、候補者の技術スキル、プロジェクトの経験、業界のトレンドの理解を評価するように設計されています。したがって、候補者はこれらの分野で自分の能力と専門知識を証明するために十分な準備をしておく必要があります。

当初、JS はブラウザ側でのみ動作していたため、Unicode でエンコードされた文字列の処理は簡単でしたが、バイナリ文字列や非 Unicode エンコード文字列の処理は困難でした。バイナリは、コンピュータのビデオ/オーディオ/プログラム/ネットワーク パッケージの最低レベルのデータ形式です。

インターネット技術の発展に伴い、フロントエンド開発の重要性がますます高まっています。特にモバイル デバイスの人気により、効率的で安定しており、安全で保守が容易なフロントエンド開発テクノロジーが必要です。 Go 言語は、急速に発展しているプログラミング言語として、ますます多くの開発者によって使用されています。では、フロントエンド開発に Go 言語を使用することは可能でしょうか?次に、この記事ではフロントエンド開発にGo言語を使用する方法を詳しく説明します。まずはフロントエンド開発にGo言語が使われる理由を見てみましょう。多くの人は Go 言語は
