在 Angular 组件中放置 JavaScript 监听函数的最佳位置是什么?
What is the best place to put a JavaScript listening function in Angular component?
TL;DR:
我正在 iFrame
内的 Angular 5 应用程序中渲染 BioDigital HumanAPI 解剖模型。我实例化 API 对象使用:
this.human = new HumanAPI(iFrameSrc);
有一个 API 函数 human.on(...)
可用于从 iFrame
中注册点击事件(例如从模型中拾取对象等)。我需要这个功能才能随时收听事件。我执行对象实例化并将此函数放在 ngOnInit()
中并且它可以工作,但是当我更改 iFrame
的源以呈现不同的模型时,此函数停止工作。我应该把这个监听函数放在哪里,让它的逻辑随时可用?
更长的版本:
我正在使用 BioDigital HumanAPI 开发一个 Angular 应用程序。这里的基本思想是 HumanAPI 提供了几个解剖模型,可以使用 iFrame
(示例 here)在网络应用程序中呈现这些模型。这个 iFrame
的 src
是一个 link,类似于:
https://human.biodigital.com/widget?m=congestive_heart_failure
因为我希望我的 Angular 应用程序的用户能够查看其中几个这样的模型,所以我有这些 URL 的列表,并且根据用户的选择,我更新了 src
iFrame
,使用具有以下代码的函数 updateFrameSrc
:
iframeSrc: SafeUrl;
this.iframeSrc = this.sanitizer.bypassSecurityTrustResourceUrl(newUrl);
最后(问题来了,请耐心等待),为了在 iFrame
本身的模型中操作和注册不同的点击事件和用户交互,我们制作了一个 HumanAPI 像这样的对象:
this.human = new HumanAPI(iFrameID);
这让我们可以使用 API 事件侦听器函数,例如 human.on('scene.picked')
来注册和保存点击事件(如我在上面引用的示例中所示)。所有这些都工作正常。
问题是,由于我在ngOnInit()
函数中初始化了human
对象,并将human.on('scene.picked')
函数放在那里,我无法在[=16]之后注册点击事件=] 来源已更改。据我了解,ngOnInit()
只在组件第一次初始化时被调用一次,所以可能是 human.on
的监听逻辑在更新iFrame
来源?我试过将逻辑放在不同的生命周期挂钩中,但它不起作用。
我目前的解决方法 是在更新 iFrame
源后重新调用 ngOnInit()
函数,它是这样工作的,但我相信这有悖于标准的生命周期管理实践。
我的问题是:
- 是否可以从组件逻辑中重新调用
ngOnInit()
函数?
- 如果不是,我应该在哪里放置一个 JavaScript API 函数,它始终监听来自
iFrame
的点击事件,即使在那个 iFrame
的来源之后] 改了吗?
如果您正在寻找近实时,您会希望这发生在 NgOnChanges 生命周期挂钩中。请注意,这很昂贵。
如果 "near real time" 稍微少一点是可以接受的,我建议在组件初始化 NgOnInit 时连接一个快速延迟主题 Observable.Interval(500)
(同样,但稍微便宜一点)。
请不要通过重新调用 ngOnInit 来绕过挂钩。
如果您还有其他问题,请告诉我。
正如之前评论中所建议的那样,您只需将 ngOnInit()
中的代码移动到一个单独的函数中,然后从 ngOnInit()
和您的更新函数中调用该函数。
在更新 iFrame
源代码时,不要忘记在该函数中重新初始化 HumanAPI
的 human
对象。
应避免重新调用 ngOnInit()
,因为它绕过了生命周期挂钩的可接受功能,如 @iHazCode 所述。
TL;DR:
我正在 iFrame
内的 Angular 5 应用程序中渲染 BioDigital HumanAPI 解剖模型。我实例化 API 对象使用:
this.human = new HumanAPI(iFrameSrc);
有一个 API 函数 human.on(...)
可用于从 iFrame
中注册点击事件(例如从模型中拾取对象等)。我需要这个功能才能随时收听事件。我执行对象实例化并将此函数放在 ngOnInit()
中并且它可以工作,但是当我更改 iFrame
的源以呈现不同的模型时,此函数停止工作。我应该把这个监听函数放在哪里,让它的逻辑随时可用?
更长的版本:
我正在使用 BioDigital HumanAPI 开发一个 Angular 应用程序。这里的基本思想是 HumanAPI 提供了几个解剖模型,可以使用 iFrame
(示例 here)在网络应用程序中呈现这些模型。这个 iFrame
的 src
是一个 link,类似于:
https://human.biodigital.com/widget?m=congestive_heart_failure
因为我希望我的 Angular 应用程序的用户能够查看其中几个这样的模型,所以我有这些 URL 的列表,并且根据用户的选择,我更新了 src
iFrame
,使用具有以下代码的函数 updateFrameSrc
:
iframeSrc: SafeUrl;
this.iframeSrc = this.sanitizer.bypassSecurityTrustResourceUrl(newUrl);
最后(问题来了,请耐心等待),为了在 iFrame
本身的模型中操作和注册不同的点击事件和用户交互,我们制作了一个 HumanAPI 像这样的对象:
this.human = new HumanAPI(iFrameID);
这让我们可以使用 API 事件侦听器函数,例如 human.on('scene.picked')
来注册和保存点击事件(如我在上面引用的示例中所示)。所有这些都工作正常。
问题是,由于我在ngOnInit()
函数中初始化了human
对象,并将human.on('scene.picked')
函数放在那里,我无法在[=16]之后注册点击事件=] 来源已更改。据我了解,ngOnInit()
只在组件第一次初始化时被调用一次,所以可能是 human.on
的监听逻辑在更新iFrame
来源?我试过将逻辑放在不同的生命周期挂钩中,但它不起作用。
我目前的解决方法 是在更新 iFrame
源后重新调用 ngOnInit()
函数,它是这样工作的,但我相信这有悖于标准的生命周期管理实践。
我的问题是:
- 是否可以从组件逻辑中重新调用
ngOnInit()
函数? - 如果不是,我应该在哪里放置一个 JavaScript API 函数,它始终监听来自
iFrame
的点击事件,即使在那个iFrame
的来源之后] 改了吗?
如果您正在寻找近实时,您会希望这发生在 NgOnChanges 生命周期挂钩中。请注意,这很昂贵。
如果 "near real time" 稍微少一点是可以接受的,我建议在组件初始化 NgOnInit 时连接一个快速延迟主题 Observable.Interval(500)
(同样,但稍微便宜一点)。
请不要通过重新调用 ngOnInit 来绕过挂钩。
如果您还有其他问题,请告诉我。
正如之前评论中所建议的那样,您只需将 ngOnInit()
中的代码移动到一个单独的函数中,然后从 ngOnInit()
和您的更新函数中调用该函数。
在更新 iFrame
源代码时,不要忘记在该函数中重新初始化 HumanAPI
的 human
对象。
应避免重新调用 ngOnInit()
,因为它绕过了生命周期挂钩的可接受功能,如 @iHazCode 所述。