Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/467.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 角度2指令事件输出中的更改检测不工作_Javascript_Angular_Events_Directive - Fatal编程技术网

Javascript 角度2指令事件输出中的更改检测不工作

Javascript 角度2指令事件输出中的更改检测不工作,javascript,angular,events,directive,Javascript,Angular,Events,Directive,我使用这个指令。但是,在setAddress事件输出上,在我的组件中未检测到任何更改。视图未更新。我不明白 对于测试,如果我删除google.maps.event.addListener以替换为调用invokeEvent的简单setTimeout。它起作用了 @Directive({ selector: '[googleplace]', providers: [NgModel], host: { '(input)' : 'onInputChange()' } }) exp

我使用这个指令。但是,在setAddress事件输出上,在我的组件中未检测到任何更改。视图未更新。我不明白

对于测试,如果我删除google.maps.event.addListener以替换为调用invokeEvent的简单setTimeout。它起作用了

@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() {
  }
}

place\u changed
的处理程序正在角度区域外运行。您需要像这样运行它:

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
  });

另一种可能的解决方案是注入
ApplicationRef
并调用
tick()
方法来运行更改检测周期:

export class GoogleplaceDirective  {

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

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

杰出的Thankssince事件发射器更新父组件上的值,而不管它运行在哪个区域,另一种方法可以是只注入
app:ApplicationRef
,然后调用
app.tick()
,如果在父组件上更新时会初始化某些内容,那么在下一个操作中可能会出错。您必须运行detectChanges或勾选again@yurzui,很有趣,你可以创建一个plunker来显示它吗?这就是为什么angular包含
这个.zone。运行
订阅Сhoose,然后单击
将地址更改为dd
按钮。然后强制updateSee zone primer
当安排异步工作时,回调函数将在调用异步API时存在的区域所在的同一区域中执行。这允许跨多个异步调用跟踪区域。
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
  });
export class GoogleplaceDirective  {

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

  invokeEvent(place:Object) {
    this.setAddress.emit(place);
    this.app.tick(); <-----------------------------------
  }
_this._zone.onMicrotaskEmpty.subscribe({
    next: function () {
        _this._zone.run(function () {
            _this.tick();
        });
    }
});