Change Detect not working in directive event ouput in Angular 2

*爱你&永不变心* 提交于 2019-12-20 03:17:23

问题


I use this directive. However, on the setAddress event output, no changes are detected in my component. The view is not updated. I d'ont understand.

For test, if i remove the google.maps.event.addListener to replace by a simple setTimeout to call invokeEvent. It works.

@Directive({
  selector: '[googleplace]',
  providers: [NgModel],
  host: {
    '(input)' : 'onInputChange()'
  }
})
export class GoogleplaceDirective  {
  @Output() setAddress: EventEmitter<any> = new EventEmitter();
  modelValue:any;
  autocomplete:any;
  private _el:HTMLElement;


  constructor(el: ElementRef,private model:NgModel) {
    this._el = el.nativeElement;
    this.modelValue = this.model;
    var input = this._el;
    this.autocomplete = new google.maps.places.Autocomplete(input, {});
    google.maps.event.addListener(this.autocomplete, 'place_changed', ()=> {
      var place = this.autocomplete.getPlace();
      this.invokeEvent(place);
    });
  }

  invokeEvent(place:Object) {
    this.setAddress.emit(place);
  }


  onInputChange() {
  }
}

In my component view

<input type="text" class="validation-address-input" style="margin-top: 100px;" [value]="form.customerAddress"
               (setAddress)="setCustomStartLocation($event)" googleplace>

In my component

/**
     *
     * @param place
     */
    setCustomStartLocation(place: Object) {
        this.currentStep = 2;
    }

回答1:


Handler for place_changed is running outside angular zone. You need to run it like this:

constructor(..., private zone: NgZone) {
  ...
  google.maps.event.addListener(this.autocomplete, 'place_changed', ()=> {
    var place = this.autocomplete.getPlace();
    this.zone.run(() => this.invokeEvent(place)); // run inside angular zone
  });



回答2:


Another possible solution is to inject ApplicationRef and call tick() method to run change detection cycle:

export class GoogleplaceDirective  {

  constructor(private app: ApplicationRef, ...) {
    ...
  }

  invokeEvent(place:Object) {
    this.setAddress.emit(place);
    this.app.tick(); <-----------------------------------
  }

This is essentially what zone is doing:

_this._zone.onMicrotaskEmpty.subscribe({
    next: function () {
        _this._zone.run(function () {
            _this.tick();
        });
    }
});


来源:https://stackoverflow.com/questions/44086130/change-detect-not-working-in-directive-event-ouput-in-angular-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!