简体   繁体   English

在Angular组件中放置JavaScript侦听功能的最佳位置是什么?

[英]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: iFramesrc是一个链接,类似于:

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函数来更新iFramesrc

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: 我的问题是:

  • It is acceptable to re-call the ngOnInit() function from within the component logic? 是否可以从组件逻辑中调用ngOnInit()函数?
  • If not, where should I place a JavaScript API function that listens to click events from an 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源文件时,也不要忘记在该函数中重新初始化HumanAPIhuman对象。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM