Skip to Content

Reuse Component: Old controller remains?

Hello,

I have a reuse component embedded in another app.

I use component based routing. Our UI5 version is 1.71.

When a button is pressed in the parent component, it publishes an event and the child component handles it.

EventBus is used for this purpose.

When the app is executed for the first time after browse refresh, this is successful.

However, when I go back to the launchpad and enter the app again, the same event is received by multiple child controllers.

It looks as if old controller remains and reacts to the event.

What I have done so far are:

1. Unsubscribe to the event in onExit hook of child's controller

2. In child's Component.js, implemented destroy function

destroy: function () {
    UIComponent.prototype.destroy.apply(this, arguments);
}

As a workaround, I checked if the controller is executed for the first time or not.

But I would like to destroy the child component each time the app is closed.

How can I achieve this?

Best regards,

Mio

pic1.png (22.6 kB)
Add a comment
10|10000 characters needed characters exceeded

Assigned Tags

Related questions

2 Answers

  • Best Answer
    Posted on Jul 10, 2020 at 01:39 PM

    Hi Mio,

    it's great to see that you use the type "Component" target with prefix in your application already! And thank you for confirming that the nested component is destroyed once the parent component is destroyed.

    The issue occurs because UI5 doesn't take care of the deregistration of the event handler that has been attached to the global EventBus object. A quick solution would be to do this in the destroy function of the nested component that you already overwrite:

    destroy: function () {
        UIComponent.prototype.destroy.apply(this, arguments);
    // here you can deregister the event handler from the eventbus }

    This should already solve the issue that you are currently facing. But I want to give you some other idea to avoid the usage of EventBus in another answer because I don't have time to write it right now and I want to give you the current solution as soon as possible.

    Best regards,

    Jiawei

    Add a comment
    10|10000 characters needed characters exceeded

    • Hi Jiawei,

      Thank you for your advice. The issue was resolved with the following way.

      First, I moved the code for subscribing parent's event from controller to Component.js, so that I can deregister the event in Component's destroy method.

      		metadata: {
      			manifest: "json",
      			events: {
      				parentEvent: {
      					parameters: {
      						data: {type: "object"}
      					}
      				}
      			}
      		},
      
      		init: function () {
      			// ...
      			
      			// subscribe to parent's event
      			this._oEventBus = sap.ui.getCore().getEventBus(); //global
      			this._oEventBus.subscribe("parent-to-child", "notify", this.oHandleEvent, this);			
      		},
      		
      		oHandleEvent: function (oData) {
                              // Notify controller
      			this.fireParentEvent({
      				data: oData
      			});
      		},
      		
      		destroy: function () {
      			// unsubscribe to parent's event
      			this._oEventBus.unsubscribe("parent-to-child", "notify", this.oHandleEvent, this);
      			UIComponent.prototype.destroy.apply(this, arguments);
      		}
      

      In the controller, I registered handler for Component's event.

      This way, the controller doesn't have to care about the deregistration.

      		onInit: function () {
      			this.getOwnerComponent().attachParentEvent(this.oHandleEvent.bind(this));
      			this._randomNumber = Math.floor(Math.random() * 100);
      		},
      		
      		oHandleEvent: function (oEvent) {
      			MessageToast.show("Event received No: " + this._randomNumber);
      		},
      

      I used EventBus to realize interactive event exchange between parent and child.

      I would like to know other way than using EventBus (maybe in your Blog post or somewhere?).

      Anyway, thank you so much for your support with this issue.

      Best regards,

      Mio

  • Posted on Jul 09, 2020 at 11:44 AM

    Hi Mio,

    all of the nested component instances that are loaded by the router in the root component should be destroyed once the root component is destroyed. In your case, it looks like something went wrong and didn't get the nested component managed by the router of the root component.

    Did you define a type "Component" target in the routing configuration of your root component in order to get it loaded by routing in your root component? Can you paste your routing configuration regarding the routes and targets definition here?

    Best regards,

    Jiawei

    Add a comment
    10|10000 characters needed characters exceeded

Before answering

You should only submit an answer when you are proposing a solution to the poster's problem. If you want the poster to clarify the question or provide more information, please leave a comment instead, requesting additional details. When answering, please include specifics, such as step-by-step instructions, context for the solution, and links to useful resources. Also, please make sure that you answer complies with our Rules of Engagement.
You must be Logged in to submit an answer.

Up to 10 attachments (including images) can be used with a maximum of 1.0 MB each and 10.5 MB total.