Я пытаюсь загрузить параметры выбора асинхронно из удаленного источника (API календаря Google).
Я могу загружать параметры удаленно из источника, отличного от Google: stackblitz
Но когда я пытаюсь загрузить из Google API, он не отображает параметры, ПОКА я не нажимаю раскрывающийся список выбора ИЛИ Я устанавливаю значение (FormControl.setValue()) одним нажатием кнопки.
Почему? Единственный способ заставить его работать - это вызвать в ChangeDetectorRef.detectChanges(); после звонка в FormControl.setValue().
Здесь - это стек, который показывает проблему.
Несколько замечаний по поводу неработающего stackblitz:
ShiftCals.Console в stackblitz. Он сообщит вам, когда выбранные параметры (календари) были загружены из Google API.set 1st option приведет к повторному рендерингу выбора.Я подозреваю, что проблема связана с некоторыми проблемами с синхронизацией, но я не могу этого понять. Заранее спасибо за помощь.
хм, не понимаю, что вы имеете в виду - вы можете спросить по-другому?
Не могли бы вы предоставить полный исходный код вашего компонента?
Есть ли причина, по которой у вас есть matNativeControl вместо того, чтобы делать элемент mat-select в соответствии с документацией? Кроме того, можете ли вы подтвердить, какую версию Angular-Material вы используете?
IMO легче выбирать на мобильных устройствах при использовании собственного выбора. @ angular / материал 7.0.3. Я обновил свой q. Благодарность
Простым решением было бы просто вызвать angular.io/api/core/ChangeDetectorRef detectChanges.
Я не уверен, но думаю, что проблема связана с async и ngZone
this.ref.detectChanges(); сделал свое дело, но это похоже на взлом. Я согласен, что это, вероятно, проблема с синхронизацией, связанная с async, однако загрузка удаленных данных для использования в select должна быть очень распространенным шаблоном. Мне сложно найти наглядный пример использования этого шаблона. Вы думаете, если я сделаю calendarList и Observable и сделаю let cal of calendarList | async, это сработает? Думаю, нет.
Готовлю ответ, но есть несколько вопросов - зачем вам сравнивать? Это множественный выбор? Я определенно думаю, что вам нужен async на вашем *ngFor
спасибо заранее @nclarx. Добавление `| async` выдает ошибку, поскольку calendarList - это просто простой список JS. В документации предлагается использовать compareWith при загрузке удаленных данных. Пример: я перезагружаюсь с удаленного компьютера, возвращаемые данные не меняются, но angular этого не знает. @ см. angular.io/api/forms/…. Завтра я поработаю над примером stackblitz, если не смогу в ближайшее время в этом разобраться.
Если вы сделаете Stackblitz, я буду счастлив поиграть с ним - у меня есть аналогичная вещь, которую я решил в одном из своих проектов. Может быть, быстрее, чем я, предоставлю здесь что-нибудь, что не по плану. Напишите ссылку в qtn, и я посмотрю на Stackblitz
Я реорганизовал использование Observable, и он по-прежнему работает, только если this.ref.detectChanges(); вызывается ПОСЛЕ this.calendarListControl.setValue(). ТАК расстраивает. Завтра буду работать над stackblitz.
@nclarx Я добавил 2 stackblitzes. 1-й работает, как я ожидал, при загрузке из удаленного источника, 2-й при загрузке через Google API (не работает). Заранее спасибо за помощь.





Я понял.
Ответ заключается в том, как Angular обнаруживает изменения. Сообщение в блоге Зоны в угловом объясняет это лучше всего, но, вкратце, Angular полагается на изменения состояния (события, удаленные выборки и т. д.), Чтобы инициировать обнаружение изменений. Эти изменения состояния отслеживаются, только если они происходят в угловой зоне.
Мой stackblitz с проблемой выходит из зоны, потому что, я думаю, часть Google JS (gapi.load()) работает в iFrame. В любом случае именно здесь выполнение выходит из зоны Angular.
Вот обновленный stackblitz с реализацией, которая работает.
Что я здесь сделал, так это обернул gapi.load() в Promise, контекст которого находится в зоне. Кроме того, разрешение Promises - это событие, которое запускает логику обнаружения изменений Angular.
Новичку в Angular вроде меня было непросто отследить это, но я многому научился. Если эта тема вас интересует, это сообщение в блоге сделает еще один шаг и поговорит о том, как улучшить качество рисования.
Вы используете push?