Как обновить представление после изменения в angular2 после запуска прослушивателя событий Google

18

Я пытаюсь обновить представление после запуска прослушивателя событий. Однако изменение не обнаруживается и не обновляется до тех пор, пока не будет обнаружено другое изменение.

import {
  Component, View, bootstrap
} from 'angular2/angular2';

@Component({
  selector: 'app'
})
@View({
  template: '{{keyword}} <input id="keyword" /><br/><span (click)="update()">{{click}}</span>'
})
class App {
  keyword;
  autocomplete;
  click;
  
  constructor() {
    var _this = this;
    var input = (document.getElementById('keyword'));
    this.autocomplete = new google.maps.places.Autocomplete(input);
    google.maps.event.addListener(this.autocomplete, 'place_changed', function(){
      console.log('place change');
      _this.keyword = "updated text";
      _this.click = "not clicked";
    });
    this.keyword = "original text";
    this.click = "click me after selection is made to force change";
  }
  
  update() {
    console.log("click");
    this.click = "clicked";
  }
  
}

bootstrap(App);
<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css" />
    <script data-require="[email protected]" data-semver="2.1.4" src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src="https://jspm.io/system.js"></script>
    <script src="https://code.angularjs.org/2.0.0-alpha.30/angular2.dev.js"></script>
    <script src="https://maps.googleapis.com/maps/api/js??v=3.exp&libraries=places"></script>
  </head>

  <body>
    <app></app>
    
    <script>
      System.import('main');
    </script>
  </body>

</html>

Если вы измените местоположение на входе, текст влево должен измениться. Он изменяется только после обнаружения другого изменения, например, нажав на текст ниже.

Что я делаю неправильно и как мне это сделать?

    
задан ComputerWolf 11.07.2015 в 03:01
источник
  • Я знаю, что это старое ... но это можно сделать в угловом v5 ?? ... iam прослушивает событие «cluster_click», но диалог углового материала не инициализируется –  TomP 25.01.2018 в 09:43

2 ответа

34

@jhadesdev привел меня в правильном направлении, но вместо zone.runOutsideAngular() мне понадобилось zone.run() . Вот полный код javascript, который работал:

import {
  Component, View, bootstrap, NgZone
} from 'angular2/angular2';

@Component({
  selector: 'app'
})
@View({
  template: '{{keyword}} <input id="keyword" /><br/><span (click)="update()">{{click}}</span>'
})
class App {
  keyword;
  autocomplete;
  click;
  zone: NgZone;
  
  constructor(zone:NgZone) {
    this.zone = zone;
    var input = (document.getElementById('keyword'));
    this.autocomplete = new google.maps.places.Autocomplete(input);
    google.maps.event.addListener(this.autocomplete, 'place_changed', ()=>{
      this.zone.run(() => {
      console.log('place change');
      this.keyword = "updated text";
      this.click = "not clicked";
      });
    });
    this.keyword = "original text";
    this.click = "click me after selection is made to force change";
  }
  
  update() {
    console.log("click");
    this.click = "clicked";
  }
  
}

bootstrap(App);
    
ответ дан ComputerWolf 11.07.2015 в 19:29
источник
  • Все еще работает с альфа-35? –  lame_coder 28.09.2015 в 06:35
  • работает в версии 2.0.0-beta.0 –  stevethecollier 28.12.2015 в 03:57
  • работает в версии 2.0.0-beta.14. Просто не забудьте импортировать NgZone из 'angular2 / core' –  Mono 13.04.2016 в 21:31
  • спасибо. отличный образец кода –  rajkiran 14.07.2017 в 02:54
  • работает также для Angular 4 –  Kamil Kiełczewski 07.08.2017 в 22:38
8

Я думаю, что проблема заключается в том, что поле выбора автозаполнения абсолютно позиционируется в конце элемента тела страницы, и поэтому вне зоны, которая отслеживается угловым (который находится внутри div, где app is).

Чтобы изменить это, выполните следующие действия:

  • добавьте CSS, чтобы поместить поле выбора относительно (используя !important ), чтобы он оставался внутри зоны

  • запустить обнаружение изменений вручную, используя NgZone :

    zone.run(() => {
      console.log('place change');
      _this.keyword = "updated text";
      _this.click = "not clicked";
    });
    
ответ дан Angular University 11.07.2015 в 10:12
источник
  • Спасибо, это привело меня к правильному ответу. Мне нужно было использовать zone.run (), а не zone.runOutsideAngular. –  ComputerWolf 11.07.2015 в 19:30
  • Похоже, что он больше не работает с альфа-35, любая идея почему? –  lame_coder 28.09.2015 в 06:37