Search code examples
sapui5

attachRoutePatternMatched() and attachMatched() called multiple times at every navigation


I would like to fire an event every time I switch between the views in UI5.
To avoid a code duplication, I define an attachRoutePatternMatched() inside of a BaseController, which all views' controllers are base on:

onInit() {

    const router = this.getOwnerComponent().getRouter();

    router.attachRoutePatternMatched((event) => {

        this.onViewSwitch(event);

    }, this);

},

onViewSwitch(event) {

    console.log("Bingo, a view switch occurred!");

}

It works but the problem is that onViewSwitch() is called several times, e.g., if I put a breakpoint, then I reach this function multiple times although just a single navigation made within the SideNavigation inside of tnt:sideContent component.

I also tried replacing attachRoutePatternMatched() with attachMatched() and providing the specific view name:

router.getRoute("wantedView").attachMatched((event) => {

    this.onViewSwitch(event);

}, this);

But still at every navigation a breakpoint inside of onViewSwitch() is reached about 5 times.

What I don't get, why and where onViewSwitch() is called so much times?

Update:

Moving attachRoutePatternMatched() from BaseController's onInit() to the onInit() of the rootView's controller solves the issue but I'm still curious to know why onViewSwitch() is called multiple times being defined in BaseController's onInit().


Solution

  • You pretty much already answered your question in the latest update.

    The onInit is called once for every view. In other words, even though you code it once, there is a onInit for every view.

    Everytime the onInit the callback, you create a local callback function.

    () => {
     this.onViewSwitch(event);
    }
    

    So in the end, once the event happens, all previously registered callbacks are called. So, you have many callbacks doing pretty much the same thing on the occurence of the event - which might led to odd behaviors like the app gettings slower and slower depending on what you are doing on the callback.

    Notice that the event itself in your scenario is not the problem. However, keep in mind that some events can be found both in the Router class and in the Route class and their behavior is different as the first is valid for any route and the later is only valid to the route being used when calling the attach function.

    Finally, consider doing your logic inside the Component.js as the Router is probably declared there unless you are doing changing the basic structure of your app. You can register the callback for any event of the Router inside the onInit of the Component.