当@Input 从 google 地图标记事件更新时,ngFor 不更新

ngFor not updating when @Input updated from google map marker event

我正在尝试使用 angular2 构建一个简单的应用程序,我有以下组件:

@Component({
    selector: 'map-menu',
    templateUrl: './angular-app/components/map-menu.html'
})
export class MapMenuComponent {
    @Input() selectedMarkers: Array<google.maps.Marker>;
    constructor() {
    //      setInterval(() => {
    //          console.log(this);
    //      }, 1000);
        }
    }

当我的地图-menu.html 是:

<ul class="nav nav-sidebar">
    <li *ngFor="#marker of selectedMarkers #i = index"><a href="#">{{marker.data.name}}</a></li>
</ul>

在我的应用程序中 html 我有:

<map-menu [selectedMarkers]="selectedMarkers"></map-menu>

并且列表没有更新,但是当我添加注释的 setInterval 时它工作正常。我在那里错过了什么?

我用解决方案

创建了一个plunker

来自User Input dev guide

Angular only updates the bindings (and therefore the screen) if we do something in response to asynchronous events such as keystrokes.

我猜你在标记数组更新时没有异步事件,因此没有任何东西导致 Angular 到 运行 它的变化检测算法。

更新: 问题不是没有异步事件,而是异步事件 (google.maps.Marker.addListener()) 不为 Angular,因此 Zone 不会对其进行猴子修补,因此 Angular 不会 运行 其在数据更改时的更改检测算法。解决方案是在 Zone 的 run() 函数中发出事件:

marker.addListener('click', () => {
   this.zone.run(() => {
      this.markerClickEvent.next({data:{name: 'another'}});
   });
});

这将导致 Angular 到 运行 它的变化检测算法,注意变化,并更新视图。

setInterval() 之所以有效是因为它是由 Zone 修补的猴子。

有关详细信息,请参阅 DiSol's plunker
如果您想了解有关 Zone 的更多信息,请观看 Miško's video
另见 NgZone API doc