問題タブ [zonejs]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
angular - NgZone がこの問題を解決するのはなぜですか?
ユーザーが自分の Google アカウントを介して自分自身を識別できるアプリケーションを作成しています。舞台裏では、gapi を使用してログインを処理しています。一方、ユーザーObservable
の状態(オンライン/オフライン)が変化するたびに加入者に情報をブロードキャストする「ユーザー」と呼ばれる角度のあるサービスがあります。次に、すべてを結合するためにボタンがあり、ユーザーがそれをクリックすると、次のようになります。
- gapi が初期化されると解決される promise が作成されます。(以下のコードの 1 行目)
- promise が解決されると、gapi を介して Google ログインが実行されます。(以下のコードの 2 行目)
- ログインの約束が解決されると、AJAX リクエスト ID がバックエンドに対して行われ、Google トークンが検証され、電子メール、名前などの情報が返され、このオブザーバブルにサブスクライブされます。
this.restService
(以下のコードの で始まる行) - 上記のオブザーバブルが Web サービスによって返された値を発行するとき、ユーザーのステータスのオブザーバブルの値を発行する「ユーザー」サービスの関数を呼び出します (ユーザーが現在認証されているという事実をブロードキャストします)。
- 次に、すべてのサブスクライバーがこの情報を受け取り、ユーザーがログインしていることを認識します。
コードは次のとおりです。
問題は、コードが機能する場合と機能しない場合があることです。調査の結果、これは Web サービスの実行時間に関連していることに気付きました。これを確実にするために、リクエストの実行を2秒間一時停止するステートメントを内部に作成しました。その場合、コードは常に失敗します。しかし、「失敗」とはどういう意味ですか?
ページのどこかに、ユーザー サービス オブザーバブルにサブスクライブするコンポーネントがあります。
Web サービスが非常に高速に実行されると、 が表示されconsole.log
、canPostComment
プロパティが更新され、ビューも更新されるため、問題はありません。ただし、Web サービスに少し時間がかかるconsole.log
と、正しい値が表示されますが、ビューは更新されません...
Angular の変更検出と関係があるのではないかと疑って、次のようにゾーンを使用します。
そして、それは機能します...だから、ゾーンについて読んで、変更検出(またはそのようなもの...)を実行する必要があることをangularに警告するために使用されていることを知りましたが、setTimeout
またはAJAX呼び出しのような一般的な機能も読みましたすでに「ゾーン」によってモンキーパッチが適用されているため、問題がどのように解決されるのかわかりません。また、この問題が発生する理由もわかりません。canPostComment
Angularが変更を認識しないのはなぜですか?
私のコードは少し複雑なので、それを plunkr するのはかなり難しいでしょう。そのため、関連するコードのほとんどをコピーして貼り付けます。
編集
質問した後、ログイン プロセス全体がいつ完了したかを知る必要があったため、コードを少し変更する必要がありました。実際、ユーザーがログイン ボタンをクリックすると、そのキャプションが「Logging in...」になり、プロセス全体が完了すると消えます。オブザーバブルを購読することuserService.getStatus
もできましたが、次のことができるという約束をすることにしました。
したがって、上記のコードを次のように更新しました。
好奇心から、this.zoneService.run
何が起こるかを確認するためだけにステートメントを削除しようとしましたが、それがなくても機能することがわかりました...すべてを約束に入れると問題が解決するようです...しかし、問題はまだ残っています...なぜ最初の例は機能しませんでしたか?