2017-04-19 22 views
0

を更新していない私は、この入力フィールドを持っている:は角度データリストDOM要素

<input type="text" list="myList"> 
<datalist id="myList"> 
    <option *ngFor="let loc of locationList">{{ loc.description }}</option> 
</datalist> 

これは非常に簡単なものです。 datalistはオートコンプリートオプションを提供し、配列によって取り込まれます。配列はサービスによって更新されます。

ここで問題が発生します。それにもかかわらず、サービスがアレイをアップグレードしても、コンソールで確認できます。実際には更新中です。datalistの内容は、別のキーを押すまで変更されません。

クロムで私はChangeDetectorRef.detectChanges()がこの問題を解決することを発見しました。しかしFirefoxの下ではそれはそのままです。ユーザーがBackspaceを押すと、Firefoxはdatalistを更新します。彼はちょうどタイピングを続けていない。

この配列に関連付けられたすべてのバインディングを更新するようにAngularに指示する方法はありますか?

答えて

0

あなたのサービスはlocationListを同期して更新すると思います(XHRやタイムアウトの結果ではありません)。これは、Angularの変更検出とリフレッシュ戦略とゾーン(zone.js)が原因です。次の記事をチェックし、それはそれについての詳細を知っておくことが重要です:

+0

実際にGoogle Maps JS APIを呼び出し、Observableを返します。ありがとう、私はチェックします。 –

0

:私はあなたが昔ながらの方法で使用することをお勧め :ここではより詳細な実施例を

query: string; 
locationList: []; 

filter() { 
    if (this.query !== ""){ 
     this.locationList = this.service.getLocations().filter(function(el){ 
      return el.toLowerCase().indexOf(this.query.toLowerCase()) > -1; 
     }.bind(this)); 
    }else{ 
     this.locationList = []; 
    } 
} 

select(item){ 
    this.query = item; 
    this.locationList = []; 
} 

<div class="container" > 
    <div class="input-field col s12"> 
     <input type="text" class="validate filter-input" [(ngModel)]=query (keyup)=filter()> 
    </div> 
    <div class="suggestions" *ngIf="locationList.length > 0"> 
     <ul *ngFor="let loc of locationList" > 
      <li > 
       <a (click)="select(loc)">{{loc.description}}</a> 
      </li> 
     </ul> 
    </div> 
</div> 

は、このメソッドを使用してコンポーネントを更新しますAngularの場合、NgZone(ZoneJSフレームワークに基づく)を使用してAngularモデルを更新する必要があります。例えば

import {Component, NgZone} from '@angular/core'; 

@Component({ 
    ... 
}) 
export class YourComponent { { 

    locationList: any[]; 
    constructor(private ngZone: NgZone) {} 

    updateDataList() { 
    googleMapsToPromise().then(locations => { 
     this.locationList = location; 
     this.ngZone.run(() => { 
      console.log('model updated') 
     }); 
     } 
    } 
    } 

} 

ここドキュメント:https://angular.io/docs/ts/latest/api/core/index/NgZone-class.html

そしてここgoogleMapsToPromiseの実装例:https://jamesbedont.com/2016/03/23/GoogleMapsApiIntroduction.html#geocode

+0

それでも動作しません。 Firefoxは入力フィールドのテキストが変更され、Backspaceが押されたときにのみデータリストを更新します。他のキーは何もしません。 –

0

すべての権利。ゾーンでの手直しはここで助けられませんでした。私はそれを働かせようとするのにおよそ2日を費やし、その後それを投げ捨て、datalistを10分で置き換えました。

<input type="text" class="form-control" formControlName="location" [(ngModel)]="currentLocation"> 

<div class="panel panel-default panel-body datalist" *ngIf="locationList.length > 0 && !(locationList.length == 1 && locationList[0].description == currentLocation)"> 
    <ul> 
     <li *ngFor="let loc of locationList"><a (click)="changeLocation(loc.description)">{{ loc.description }}</a></li> 
    </ul> 
</div> 

選択肢があるときに毎回表示されるブートストラップパネルです。すべてのブラウザで動作し、更新に関する問題はありません。さらに、ユーザーがリストからオプションを選択したかどうかを検出できるため、有効な応答が得られます。ローダースピナーを追加するのも簡単です(私が実際に行ったことですが、このスニペットをシンプルにしました)。

今日教訓を受けた教訓:datalistを角度で使用しないでください。ただしないでください。