javascript – How can I call the attach / detach events with a named function? – Code Utility

[

I have a function which needs to attach and detach a handler to the event “requestCompleted” of the OData model to get the URL from the header in order to download the data as an Excel file.

onClickAction: function (oEvent) {
    var model = this.getView().getModel();
    model.attachRequestCompleted(this.downloadODataAsExcel);
    var btnGo = this.getView().byId("btn");
    btnGo.firePress();
    model.detachRequestCompleted(this.downloadODataAsExcel, this);
},

downloadODataAsExcel: function (evt) {
    var url;
    url = evt.getParameters() && evt.getParameters().url;
    url = "/sap/opu/odata/sap/ZService/" + url + "&$format=xlsx";
    sap.m.URLHelper.redirect(url, true);
},

I am trying to detach the event afterwards to prevent snowballing of the event which causes the file to download n+1 times each time you click the download button.


Update: this is the code I ended up with

onClickAction: function (oEvent) {
    var model = this.getView().getModel();
    model.attachRequestCompleted(this.downloadOdataAsExcel, this);
    var btnGo = this.getView().byId("btn");
    btnGo.firePress();
},

downloadODataAsExcel: function (evt) {
    var url;
    url = evt.getParameters() && evt.getParameters().url;
    url = "/sap/opu/odata/sap/Z_SERVICE/" + url + "&$format=xlsx";
    sap.m.URLHelper.redirect(url, true);
    var model = this.getView().getModel();
    model.detachRequestCompleted(this.downloadODataAsExcel, this);
}

The detach needs to be within the function otherwise the listener will be detached before the requestCompleted event fires.

,

Try this:

model.attachRequestCompleted(this.downloadOdataAsExcel, this);

And then try to access the ‘evt’ object.

,

Event handlers can be attached and detached by passing the same list of arguments to the methods. For example:

myModel.attachRequesCompleted(this.onRequestCompleted/*NO .bind*/, this); // Pass the oListener (this) as an argument instead
myModel.detachRequestCompleted(this.onRequestCompleted/*NO .bind*/, this); // Same list of arguments

By “same list of arguments”, I mean:

  • Do not pass an anonymous function directly as the event handler. It’s impossible to reference it later when trying to detach it.

  • Do not pass the function directly using .bind because .bind creates a new function which, again, makes detaching it impossible.

  • Pass the same oListener reference. From the API description:

    The passed function and listener object must match the ones used for event registration. (Source)

The same applies also for all attach* / detach* methods generated by the ManagedObject.

In your case, the handler couldn’t be detached because the listener object, when attaching the handler, was undefined instead of this.


Alternatively, attachEventOnce can be also used.

myModel.attachEventOnce("requestCompleted", this.onRequestCompleted, this);

Once the handler is called, it’s detached automatically.

]