简体   繁体   中英

What is the best place to put a JavaScript listening function in Angular component?

TL;DR:

I am rendering a BioDigital HumanAPI anatomical model in my Angular 5 app within an iFrame . I instantiate API object using:

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.). 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. 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. 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 ). The src of this iFrame is a link, something like:

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:

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:

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). 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. 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? 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.

My questions are:

  • It is acceptable to re-call the ngOnInit() function from within the component logic?
  • 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?

If you are looking for near real time you will want this to occur in the NgOnChanges life-cycle hook. 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.

Please DO NOT circumvent the hooks by re-calling 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.

Don't forget to re-initialize the human object of HumanAPI in that function as well, when updating the iFrame source.

Re-calling ngOnInit() should be avoided as it circumvents the acceptable functionality of lifecycle hooks, as mentioned by @iHazCode .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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