嗨,我正在从angular material谷歌地图库中读取trought代码。这一切都很清楚,但有一件事。下面的代码是我还没有理解的(来自地图事件管理器.ts(
/** Gets an observable that adds an event listener to the map when a consumer subscribes to it. */
getLazyEmitter<T>(name: string): Observable<T> {
const observable = new Observable<T>(observer => {
// If the target hasn't been initialized yet, cache the observer so it can be added later.
if (!this._target) {
this._pending.push({observable, observer});
return undefined;
}
const listener = this._target.addListener(name, (event: T) => {
this._ngZone.run(() => observer.next(event));
});
this._listeners.push(listener);
return () => listener.remove();
});
return observable;
}
/** Sets the current target that the manager should bind events to. */
setTarget(target: MapEventManagerTarget) {
if (target === this._target) {
return;
}
// Clear the listeners from the pre-existing target.
if (this._target) {
this._clearListeners();
this._pending = [];
}
this._target = target;
// Add the listeners that were bound before the map was initialized.
this._pending.forEach(subscriber => subscriber.observable.subscribe(subscriber.observer));
this._pending = [];
}
尤其是这条线,我不清楚。为什么以及如何连接。让它回到ngZone内部的部分在哪里?
this._pending.forEach(subscriber => subscriber.observable.subscribe(subscriber.observer));
区域恢复:this._ngZone.run(() => observer.next(event));
Zone.js的主要目的是在异步操作发生时通知angular,并根据该angular决定是否渲染UI。
Zone处理大多数异步API,如setTimeout((,Promise.then((和ddEventListener((`。有关完整列表,请参阅区域模块文档。因此,在那些异步API中,您不需要以手动触发变化检测。
仍然有一些第三方API是Zone无法处理的。在里面在这些情况下,NgZone服务提供了一个run((方法你可以在角区内执行一个函数。此功能,以及该函数中的所有异步操作,触发更改检测自动在正确的时间。
angular无法检测到与映射相关的事件,因为这些事件被视为自定义事件,而不是任何异步API的一部分(如上所述(。这就是为什么他们明确地强制这些事件在区域内运行。因此angular可以检测这些事件并相应地触发变化检测。
有关更多信息,请参阅:https://angular.io/guide/zone
如果你在/google-map.ts中看到以下几行,他们正在将谷歌地图实例设置为setTarget函数。因此,通过使用getLazyEmitter,他们将映射特定的侦听器附加到映射实例。同样,如果您检查了google-map.ts,您可以看到它们通过声明@output事件来附加侦听器。因此,每个@output都已经具有可观察的映射侦听器。当映射事件发生时,"this"中的回调函数_target.addListener',它是将被调用的ngZone。