[英]What is the best place to put a JavaScript listening function in Angular component?
TL;DR: TL; DR:
I am rendering a BioDigital HumanAPI anatomical model in my Angular 5 app within an iFrame
. 我正在
iFrame
Angular 5应用中渲染BioDigital HumanAPI解剖模型。 I instantiate API object using: 我使用以下方法实例化API对象:
this.human = new HumanAPI(iFrameSrc);
There's an API function human.on(...)
that can be used to register click events from within iFrame
(like picking objects from the model, etc.). 有一个API函数
human.on(...)
,可用于在iFrame
注册点击事件(例如从模型中选择对象等)。 I need this function to be able to listen to the events at all times. 我需要此功能以便能够随时收听事件。 I do the object instantiation and put this function within
ngOnInit()
and it works, but when I change the source of iFrame
to render a different model, this function stops working. 我执行对象实例化并将此函数放在
ngOnInit()
并且可以工作,但是当我更改iFrame
的源以呈现不同的模型时,此函数将停止工作。 Where should I put this listening function so that its logic is available at all times? 我应该在哪里放置此侦听功能,以便其逻辑始终可用?
Longer version: 较长版本:
I am developing an Angular app using BioDigital HumanAPI. 我正在使用BioDigital HumanAPI开发Angular应用程序。 The basic idea here is that HumanAPI provides several anatomical models which can be rendered in a web-app using an
iFrame
(an example here ). 这里的基本思想是,HumanAPI提供了几个解剖模型,可以使用
iFrame
在Web应用程序中进行渲染( 此处为示例)。 The src
of this iFrame
is a link, something like: 此
iFrame
的src
是一个链接,类似于:
https://human.biodigital.com/widget?m=congestive_heart_failure
Since I want the user of my Angular app to be able to view several of such models, I have a list of these URLs, and based on user's selection, I update the src
of iFrame
, using a function updateFrameSrc
which has following code: 因为我希望Angular应用程序的用户能够查看多个这样的模型,所以我有这些URL的列表,并根据用户的选择,使用具有以下代码的
updateFrameSrc
函数来更新iFrame
的src
:
iframeSrc: SafeUrl;
this.iframeSrc = this.sanitizer.bypassSecurityTrustResourceUrl(newUrl);
Finally (the question is coming, please stay with me), in order to manipulate and register different click events and user interactions with the model within the iFrame
itself, we make a HumanAPI object like this: 最后(问题来了,请留着我),为了在
iFrame
本身中操纵和注册不同的点击事件以及与模型的用户交互,我们制作了一个HumanAPI对象,如下所示:
this.human = new HumanAPI(iFrameID);
This lets us use API event listener functions like human.on('scene.picked')
to register and save click events (like shown in the example I referenced above). 这使我们可以使用诸如
human.on('scene.picked')
类的API事件监听器函数来注册和保存点击事件(如我在上面引用的示例中所示)。 All of this is working fine. 所有这些都工作正常。
The problem is that since I initialize the human
object in the ngOnInit()
function and also put the human.on('scene.picked')
function there, I cannot register the click events after the iFrame
source is changed. 问题在于,由于我在
ngOnInit()
函数中初始化了human
对象,并且还在其中放置了human.on('scene.picked')
函数,因此在更改iFrame
源之后我无法注册click事件。 As I understand it, ngOnInit()
is only called once when the component is first initialized, so may be the listening logic of human.on
is not available after updating the iFrame
source? 据我了解,
ngOnInit()
仅在组件首次初始化时被调用一次,所以在更新iFrame
源之后, human.on
的监听逻辑可能不可用吗? I have tried placing the logic in different life-cycle hooks but its doesn't work. 我尝试将逻辑放置在不同的生命周期挂钩中,但是它不起作用。
My current work-around is to re-call the ngOnInit()
function after updating the iFrame
source, and it works that way, but I believe this is against the standard life-cycle management practices. 我当前的解决方法是在更新
iFrame
源之后重新调用ngOnInit()
函数,这种方法可以正常工作,但是我认为这违反了标准生命周期管理惯例。
My questions are: 我的问题是:
ngOnInit()
function from within the component logic? ngOnInit()
函数? iFrame
at all times, even after the source of that iFrame
has been changed? iFrame
的来源之后,我仍应始终放置一个JavaScript API函数来监听iFrame
点击事件吗? If you are looking for near real time you will want this to occur in the NgOnChanges life-cycle hook. 如果您正在寻找近乎实时的记录,则希望在NgOnChanges生命周期挂钩中发生这种情况。 Be advised this is expensive.
被告知这是昂贵的。
If slightly less "near real time" is acceptable, I would advise wiring up a rapid delay subject Observable.Interval(500)
(also, but slightly less expensive) at the time of Component initialization NgOnInit. 如果可以接受稍微少一点的“接近实时”,我建议在组件初始化NgOnInit时连接一个快速延迟的主题
Observable.Interval(500)
(也可以,但要便宜一些)。
Please DO NOT circumvent the hooks by re-calling ngOnInit. 请不要通过重新调用ngOnInit来避开钩子。
If you have additional questions let me know. 如果您还有其他问题,请告诉我。
As suggested in an earlier comment, you can just move the code in ngOnInit()
to a separate function and call that function from both ngOnInit()
as well as your update function. 如前面的注释中所建议,您可以将
ngOnInit()
的代码ngOnInit()
单独的函数,然后从ngOnInit()
和更新函数中调用该函数。
Don't forget to re-initialize the human
object of HumanAPI
in that function as well, when updating the iFrame
source. 更新
iFrame
源文件时,也不要忘记在该函数中重新初始化HumanAPI
的human
对象。
Re-calling ngOnInit()
should be avoided as it circumvents the acceptable functionality of lifecycle hooks, as mentioned by @iHazCode . 再呼叫
ngOnInit()
应避免,因为它绕过了生命周期钩的可接受的功能,如通过提及@iHazCode 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.