2017-04-30 15 views
0

入力プロパティが変更されている場合は、OnPushでマークされたコンポーネントの変更検出が実行されることを理解します(他の方法もあります)。角2変化の検出:OnPush

私の子コンポーネントには入力プロパティはなく、コンポーネントにはサービスが注入されています。私は、この子コンポーネント内のサービスによって公開されているobservableを購読しました。今、subscribeコールバックメソッドの中で、私は子コンポーネントのプライベートプロパティの値を変更します。コンポーネントのテンプレートは、このプロパティに結合されています。

問題は、オブザーバがイベントをパブリッシュして、サブスクライバコールバックが呼び出され、プロパティ値が変更されたが、ビューに変更が反映されない場合です。 UIは、自分のページのどこかをクリックすると更新されます。

changeDetection: ChangeDetectionStrategy.OnPush 

更新1:Plunkerだから

+0

非同期パイプまたは 'cdRef.markForCheck()'を使ってみましたか?あなたのコードはどこですか? – yurzui

+0

テンプレートはコンポーネント例の文字列のプライベートプロパティにバインドされるため、非同期パイプは使用できません。 CDR.markForCheck()CDを読み込んでanscetorのルートコンポーネントまで戻ってくるので、私はそれを読んだのですが、残念です。私は、プランナーを投稿する方法を知らない、Googleとすぐに追加します。ありがとう。 – thinkmmk

+0

いいえ、 'markForCheck'は先祖のルートに戻っていません。それは 'ApplicationRef.tick()'です。 'markForCheck'は、コンポーネントが次の変更検出時にスキップされないようにします。 –

答えて

1

を追加、コメントは完全に正しいです。 markForCheck()は、それがルートに上がることになりますが、それは悪いことではないのです...

をあなたのアプリが行く場合:root > section > page > area > row > list、あなたは、あなたが変更が起こった親アイテムを通知したいと思うあなたのlistの変更を行います。たぶん、より多くのデータが読み込まれるようになったり、スクロールを起動させたり、あらゆる種類のものを起動したりする必要があります。

覚えておいてください。onPush()を親にも使用している場合は、子どもがmarkForCheck()と変更されたという通知を受けずに検出があなたの子供に届くことはありません。すべての方法。あなたのコンポーネントの任意のプロパティを表示している場合

他の方法は、手動でdetectChanges()でトリガされる。これは、ローカルコンポーネント上で実行し、rootとしてdetectChanges()と呼ばれるノードを扱います。..また

、それはにISN技術的にはプライベートではない。 Javascriptはもちろんそれを可能にしますが、スイートをテストしても、私はコンパイラでさえ不平を言うと思います。何かをする必要があれば、それを公開ゲッターで表示してください。

Private _mySuperSecret: 'I am Batman'; 
Public get mySecret() { return this._mySuperSecret; }; 
+0

私はplunkerを追加するために私の質問を編集しました。また、pluckerでdetectChanges()を使うと動作しますが、detectChanges()を共有できない実際のコードではうまくいきません。しかし、markForChanges()は機能します。私は角度2.4.0のバージョンを使用しています。また、私はあなたの答えの第三段落を理解していない、あなたはそれを理解するのを助けてくれますか?私は今、私のアプリの振る舞いについて混乱しています。 – thinkmmk

+0

ええ、文はちゃんと吸います。私は、あなたが 'onPush()'である子コンポーネント(A)と、 'onPush()'である子(C)を持つ 'onPush()'という子(B)あなたが変更を引き起こす場所です。理由は 'markForCheck()'が** root **で始まり、 "変更がありますか?"そうでない場合はスキップし、子Cの変更は検出されません。したがって、実際に変更された子が検出されて更新されるように、すべての親をテストするようにマークします。 –

+0

'private'については、' private'が内部データ用に予約されています。コンポーネントのビューレイヤーを含め、どのような方法でも公開することは一般的に嫌われています。 Javascriptはもちろん気にしませんが、Typescript canとAngular Compilerもそうです。現在の4.Xブランチに移動すると、エラーが発生する可能性があります。私の例のように 'public'に切り替えるか、またはpublic read-only functionを作成してください。説明のために –

関連する問題