2017-02-03 119 views
3

我工作在一個角度2應用程序。我有一個谷歌地圖,它與自動完成。我有一個輸入(與谷歌自動完成),和一個搜索按鈕。當我點擊搜索按鈕時,我會將輸入數據發送到Google地理編碼,並在地圖上放置一個標記。這聽起來很簡單,但在此之後,angular2數據bindig停止工作。輸入沒有得到格式化的地址,addressIsValid不開啓true。谷歌地圖回調後,Angular2雙向綁定停止工作

HTML:

<div class="input-group"> 
<input autocorrect="off" autocapitalize="off" spellcheck="off" type="text" 
     class="form-control" [(ngModel)]="addressInput" #search id="address" (keydown)="addressChanged()"> 
<div class="input-group-btn"> 
    <button id="addressSubmitButton" type="submit" class="btn btn-default" [class.btn-success]="addressIsValid" 
      (click)="submited(search.value)"> 
     {{ (addressIsValid ? 'addressInput.success' : 'addressInput.search') | translate }} 
    </button> 
</div> 

代碼:不觸發

export class AddressInputComponent implements OnInit { 
public map: google.maps.Map; 
public autocomplete: google.maps.places.Autocomplete; 
private geocoder: google.maps.Geocoder = new google.maps.Geocoder(); 
public marker: google.maps.Marker; 
public defaultZoom: number; 
public defaultLat: number; 
public defaultLng: number; 
public errorCode: number; 
private addressIsValid: boolean; 
@Input('address') private addressInput: string; 
@Output() addressUpdated: EventEmitter<string> = new EventEmitter(); 

@ViewChild("search") 
public searchElementRef: ElementRef; 

constructor() { 
    this.addressIsValid = false; 
} 

ngOnInit() { 
    this.defaultZoom = 7; 
    this.defaultLat = 47.338941; 
    this.defaultLng = 19.396167; 
    this.errorCode = null; 

    this.autocomplete = new google.maps.places.Autocomplete(this.searchElementRef.nativeElement, { 
     types: ["address"] 
    }); 

    this._setMapToDefault(); 

    this.autocomplete.bindTo('bounds', this.map); 

    this.autocomplete.addListener('place_changed',() => { 
     this.addressInput = this.autocomplete.getPlace().formatted_address; 
    }) 
} 

private _setMapToDefault() { 
    this.map = new google.maps.Map(document.getElementById('map'), { 
     center: {lat: this.defaultLat, lng: this.defaultLng}, 
     zoom: this.defaultZoom, 
     scrollwheel: false, 
    }); 

    this.marker = new google.maps.Marker(); 
    this.marker.setMap(this.map); 
} 

submited() { 
    this.geocoder.geocode({ 'address': this.addressInput}, (results, status) => { 
     if (status == google.maps.GeocoderStatus.OK) { 
      setInterval(this._changeInput(results[0]), 200); 
     } else { 
      this.addressIsValid = false; 
      this.errorCode = 1; 
      this._setMapToDefault(); 
     } 
    }); 
} 

private _changeInput(result) { 
    this.errorCode = null; 

    if (result.address_components[0].types[0] != "street_number") { 
     this.addressIsValid = false; 
     this.errorCode = 2; 
     this._setMapToDefault(); 
     return; 
    } 

    // jQuery('#address').val(result.formatted_address); 
    this.addressInput = result.formatted_address; 
    this.addressUpdated.emit(this.addressInput); 
    this.addressIsValid = true; 

    this.map.setCenter(result.geometry.location); 
    this.map.setZoom(17); 
    this.marker.setPosition(result.geometry.location); 
    this.marker.setVisible(true); 
} 

private addressChanged() { 
    if (this.addressIsValid == true) { 
     this.addressIsValid = false; 
     this._setMapToDefault(); 
    } 
} 

}

回答

2

變化檢測,因爲google.maps使用它自己的套活動/電話的addListener。這些事件不是所謂的由zone.js修補的猴子,因此不會在角度區域運行,這在邏輯上不會觸發更改檢測週期。

所以,你可以通過注入在你的組件ngZone服務,可以在其上使用run方法重新輸入角度帶解決這個問題:

constructor(private ngZone: NgZone) {} 

ngOnInit() { 
    //... 
    this.autocomplete.addListener('place_changed',() => { 
     this.ngZone.run(() => { 
      this.addressInput = this.autocomplete.getPlace().formatted_address; 
     }); 
    }) 
} 
+0

我面對完全一樣的問題,我只是即將失去理智。 – Hozington