Работает ли код в зоне, и если да, то почему и как? - PullRequest
0 голосов
/ 27 февраля 2020

Привет, я читал код ошибки из angular материал библиотеки Google Map . Это все вполне понятно, но одно. Код ниже - это то, что я не понял (из map-event-manager.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));

1 Ответ

0 голосов
/ 27 февраля 2020

Основная цель Zone. js - уведомить angular, когда происходит асинхронная операция c, и на основании этого angular может решить, следует ли отображать пользовательский интерфейс.

Zone обрабатывает большинство асинхронных API, таких как setTimeout (), Promise.then () и addEventListener () `. Полный список см. В документе «Зональный модуль». Поэтому в этих асинхронных API вам не нужно вручную запускать обнаружение изменений.

Есть еще некоторые сторонние API, которые Zone не обрабатывает. В этих случаях служба NgZone предоставляет метод run (), который позволяет вам выполнять функцию внутри зоны angular. Эта функция и все асинхронные операции в этой функции автоматически инициируют обнаружение изменений в правильное время.

События, связанные с картой, не могут быть обнаружены angular, поскольку эти события рассматриваются как пользовательские события, а не как часть любых асинхронных API (упомянутых выше). Вот почему они явно заставляют эти события запускаться внутри зоны. Таким образом, angular может обнаруживать эти события и инициировать обнаружение изменений соответствующим образом.

Для получения дополнительной информации см .: https://angular.io/guide/zone

Если вы go и видите следующие строки в /google-map.ts, они устанавливают экземпляр карты Google для функции setTarget. Таким образом, используя getLazyEmitter, они присоединяют спецификаторы карты c к экземпляру карты. Опять же, если вы зарегистрируетесь в google-map.ts, вы можете увидеть, что они подключают слушателей, объявив события @output. Таким образом, у каждого @output уже есть слушатели карты как наблюдаемые. Когда происходит событие карты, вызывается функция обратного вызова в this._target.addListener, которая является ngZone.

...