用远程数据填充angular7 select选项的正确方法?

时间:2018-12-05 23:53:49

标签: angular google-api angular-material google-calendar-api

我正在尝试从远程源(Google日历API)异步加载选择选项。

我可以从非Google来源远程加载选项:stackblitz

但是当我尝试从Google API加载时,它不会呈现选项,直到我单击选择下拉列表或单击按钮设置值(FormControl.setValue())。

为什么?使它起作用的唯一方法是在调用ChangeDetectorRef.detectChanges();之后调用FormControl.setValue()

Here是显示问题的堆栈式炸弹。

关于无效堆叠的一些注意事项:

  1. 它要求您通过Google登录,并授予我的客户ID对您的日历的读取权限。您可以查看我的消息来源,发现我在做任何邪恶的事情。您也可以从google permissions page撤消访问,我的应用程序名称为ShiftCals
  2. 在堆栈闪电中打开Console。它将告诉您何时已从Google API加载选择选项(日历)。
  3. 要重新制作,请单击“使用Google登录”按钮,然后等待选择框出现。它是空的。单击选择或按set 1st option将强制重新显示选择。
  4. 要重新运行测试迭代,您需要重新加载stackblitz预览框架。

我的直觉是问题是由于某些计时问题引起的,但是我无法弄清楚。预先感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

我知道了。

答案在于Angular如何进行变化检测。 Zones in Angular博客文章对此进行了最好的解释,但简而言之,Angular依靠状态更改(事件,远程获取等)来启动更改检测。这些状态更改仅在发生在Angular Zone中时受到监视。

我的堆栈闪电with the problem之所以走出区域,是因为某些Google JS(gapi.load())运行在iFrame中-我认为。无论哪种情况,执行都是从Angular的区域中退出的。

Here is the updated stackblitz和有效的实现。

我在这里所做的是将gapi.load()包裹在一个Promise的环境中。此外,Promise的分辨率是触发Angular的更改检测逻辑的事件。

对于像我这样的Angular新手来说,这是一个艰难的过程,但是我学到了很多。如果您对这个主题感兴趣,this blog post,请更进一步,并讨论如何提高绘画效果。