2016-08-22 14 views
2

こんにちはダートと角皆さん、 を更新していないバインディング:Angular2ダーツプロパティは問題以下

私はapp_component.dartカスタムコンポーネントのテンプレートである私のapp_component.html、中に以下のテンプレートの一部を持っています。

<!-- monitoring active breakpoints--> 
 
<jb-responsive-breakpoints [breakpoints]="breakpoints" 
 
          [(activeBreakpoints)]="activeBreakpoints"> 
 
</jb-responsive-breakpoints> 
 

 
<!-- using list of active breakpoints --> 
 
<jb-menu [activeBreakpoints]="activeBreakpoints"> 
 
    <!--some menu items, irrelevant for this problem--> 
 
</jb-menu> 
 

 
<!-- testing list of active breakpoints--> 
 
Active Breakpoints: 
 
<ul> 
 
    <li *ngFor="let breakpoint of activeBreakpoints;"> {{breakpoint}}</li> 
 
</ul>

Jbの応答性 - ブレークポイントとJB-メニューもカスタムコンポーネントです。以下のulは、jb-responsive-breakpointの適切な機能をテストします。

変数「ブレークポイント」と、このテンプレートで使用される「activeBreakpointsは」次のコードでapp_component.dart内で定義されています。

//Mapping from window min-width for this breakpoint to label 
Map<int, String> breakpoints = {0:'small', 310:'medium', 450:'large', 600:'xlarge'}; 

List<String> activeBreakpoints = new List<String>(); 

何が起こる必要があります。

  • JB応答性、ブレークポイント指定された幅のリスナーを登録する
  • ウィンドウの現在の幅が1つのブレークポイントを超えると、 "activeBreakpoints"リストが更新されます。このリストには、現在アクティブなブレークポイントがすべて含まれています.cssは、一致するすべてのメディアクエリを一度に有効にします。
  • これは、テンプレートのulがそれに応じて更新されるためです。

問題:

JB-メニューは、それの外観を変更する際に、把握するactiveBreakpointsのリストを取得する必要があります。 jb-menuのactiveBreakpointsプロパティは、イベントハンドラのように設定されます。

JB-メニューのactiveBreakpointsプロパティは次のように定義されています。

List<String> _activeBreakpoints; 

@Input() 
set activeBreakpoints(List<String> breakpoints) { 
    _log.finest("ActiveBreakpoints list changed"); 
    _log.finest("Active Breakpoints: ${breakpoints.fold("", (prevVal, elem) => "$prevVal, $elem")}"); 
    _activeBreakpoints = breakpoints; 
} 

get activeBreakpoints { 
return _activeBreakpoints; 
} 

行動: - セッターは空のリストと呼ばれている - ので、初期 の論理 - いいえ、セッターがさらにブレークポイントの変更で呼び出されません(ログメッセージでこれを証明できます - ウィンドウのサイズを変更するときに "activeBreakpoints changed"ログメッセージなし) - 混乱:ngAfterViewInitのjb-menuコンポーネントにアクティブなブレークポイントを記録すると、現在のブレークポイントはすべて意図通りに表示されます:

@override 
ngAfterViewInit() { 
    _log.finest(
    ''' 
    currentBreakpoints: $activeBreakpoints 
    ''' 
); 
} 

これが生成します。

currentBreakpoints: [small, medium, large, xlarge] 

または少ないブレークポイントを、ウィンドウサイズに応じました。

これは、両方のコンポーネントで同じリスト参照が使用されているためです。

しかし、私のメニューコンポーネントは、イベントハンドラのように呼び出されるセッターに依存しています。

いくつかのアイデアを修正する方法はありますか?

PS:詳しいコードや説明が必要な場合は、お問い合わせください。:)

答えて

2

問題は、バインディングの参照が変更されていない場合は、角2は、セッターを呼び出すことはありませんので、

ので、問題がある

を解決しました。

3つの可能な解決策(ギュンターZöchbauerにクレジット):

  1. 変更すべての変更を拘束の参照。それが実現するのが最も簡単だと小さなリストを巨大なパフォーマンスの問題を作るべきではありませんので、私は、私のJB応答-ブレークポイントのコンポーネント内にこれを使用します。 eventEmitter.emit(listObject.toList())代わりにeventEmitter.emit(listObject)

  2. (唯一つのストリームイベントを放出する出力特性を回避するために)イベントを放出成分の外StreamControllerを作成し、個々のイベント

    • を有するようにストリームを使用して実施することができる
    • StreamControllerをイベントを送出するコンポーネントに渡す
    • 添付ストリームをコンポーネントに渡す/イベント放出コンポーネントからのイベントに関心のあるすべてのコンポーネント
    • ストリームは、個々のイベント
    • 結論を持っている10
    • 使用:は、私はそれを使用していませんでした。これにより、コンポーネントのユーザーはこのストリーム処理を実装する必要があります。多くのイベントを生成するイベントコンポーネントの方が優れています。
    • 代わり検討:
  3. 以下 DoCheckメソッドDoCheckインタフェースを実装し、その上に角度

    • 詳細の変更検出ajustするIterableDiffersを使用する:これはによって使用さangular.io - DoCheck Interface
    • を角度の内部で、*例えばngFor
  4. 0あなたの速い応答のための
2

(私はあなたの質問を理解してかどうかわからない - 注意して使用します)

  • Angular2変化検出は、オブジェクト参照を比較しますが、オブジェクトや配列の内容ではありません。
    あなたはそれの変化を認識する変化検出のための別のインスタンスにするために、リストcurrentBreakpoints = currentBreakpoints.toList()のコピーを作成することができます。

  • あなたは、配列の代わりにストリームを渡し、更新に関する受信機に通知するストリームを使用して新しい値を発することができます。渡された配列が同じインスタンスの場合、この配列へのバインディングはまだ更新されません。

  • DoCheckを実装し、IterableDiffersを使用して、変更検出サイクルごとに内容が変更されているかどうかを確認できます。

+0

まず、本当に大きな感謝!:) さて、私は参照を比較する点を参照してください。いくつかのテストの後、* ngForはあなたが言及している3番目のメソッドを使用しているように見え、したがって動作します。 しかし、わかりません、IterableDiffersの使い方は少しありますか?私は検索してオートコンプリートで試しましたが、使用法は私には意味がありません:D jb-menuのセッターを通常のパブリック "変数"に変更すると、値は完全に表示されます。しかし、私はこれらの値でいくつかのチェックをしなければならないので、単純なバインディングはオプションではありません。 ---次のコメントに続きます--- –

+0

さて、 'jb-responsive-breakpoints'の中で' .toList() 'を使ってactiveBreakpointsの新しいインスタンスを作ってみましょう。しかし、これは少しハッキーだと思いますか? この「DoCheck」メソッドと「terableDiffers」メソッドを使用する方が効果的かもしれませんか? –

+0

あなたはまだ書いていますか? :D https://angular.io/docs/ts/latest/api/core/index/DoCheck-class.htmlには例があります。 "public変数"についてわからない –