简体   繁体   中英

How to update view after change in angular2 after google event listener fired?

I am trying to update the view after an event listener is fired. However, the change is not detected and isn't update until another change is detected.

 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="jquery@2.1.4" 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> 

If you change the location in the input, the text to the left should change. It only is changed after another change is detected, for example clicking the text below.

What am I doing wrong and how do I do it right?

@jhadesdev led me in the right direction but instead of zone.runOutsideAngular() I needed zone.run() . Here's the full javascript code that worked:

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

I think the problem is that the selection box of the autocomplete is being absolutely positioned at the end of the body element of the page, and so outside the zone that is being tracked by Angular (which is inside the div where the app is).

To change this, either:

  • add some CSS to position the selection box relative (using !important ) to make it stay inside the zone

  • trigger the change detection manually, using NgZone :

     zone.run(() => { console.log('place change'); _this.keyword = "updated text"; _this.click = "not clicked"; }); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM