Event parameter overwritten after change event?

徘徊边缘 提交于 2021-02-08 02:10:43

问题


In view:

<List selectionChange="onSelectionChange">

In controller:

onSelectionChange : function (oEvent) {
    console.log(oEvent.sId); //log 1, output "selectionChange"
    MessageBox.warning(Utils.i18n("CHANGE_CONFIRM"), {
        actions: [Utils.i18n("LEAVE_BTN"), MessageBox.Action.CANCEL],
        onClose: function(sAction) {
            console.log(oEvent.sId); //log 2, output "closed"
            if(sAction === Utils.i18n("LEAVE_BTN")) {
                this._showDetail(oEvent.getParameter("listItem") || oEvent.getSource(), oEvent.getSource().data("target"));
            }
        }.bind(this)
    });     
}

Hi, may I ask why oEvent changed when onClose is triggered? Why can't I store oEvent in my scope?


回答1:


Event is a module that implements Poolable, meaning that Event has to implement init and reset which will then be leveraged by its corresponding ObjectPool instance ("oEventPool" internally) to reuse the existing Event instance for the next event.

The "next event", in our case, is the "close" event which was fired by the dialog. As you could already observe, oEvent suddenly doesn't have the ID "selectionChange" but "close". This is because the Event instance was reset and reused again. And since oEvent is just a reference (not a copy), and because JS applies Call by Object-Sharing, it's "changed".

The API Reference of ObjectPool explains what it's doing with the Event instance:

(ObjectPool) maintains a list of free objects of the given type. If sap.ui.base.ObjectPool.prototype.borrowObject is called, an existing free object is taken from the pool and the init method is called on this object.

When no longer needed, any borrowed object should be returned to the pool by calling #returnObject. At that point in time, the reset method is called on the object and the object is added to the list of free objects.

Currently, the (oEvent) object is considered "no longer needed" when its handler is called. So the object is already reset right after onSelectionChange, and initialized again right before onClose is triggered.

UI5 does this so that it doesn't have to create and destroy multiple Event instances to improve performance. This is a practice borrowed from the Object Pool Design Pattern (which is also often used in game development).


So, what does it mean for us as application developers? Just don't rely on the event object that is inside a closure. Instead, assign primitive values from the object to separate variables so that we can use them later. E.g.:

onSelectionChange: function(oEvent) {
  const eventId = oEvent.getId(); // === "selectionChange"
  MessageBox.warning(/*...*/, {
    onClose: function() {
      /* oEvent.getId() === suddenly "close" but
         eventId === still "selectionChange" 👍 */
    },
  });
},


来源:https://stackoverflow.com/questions/47452986/event-parameter-overwritten-after-change-event

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!