2017-11-23 2 views
2

In Ansicht:Ereignisparameter nach Änderungsereignis überschrieben?

<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) 
    });  
} 

Hallo, darf ich fragen, warum oEvent geändert, wenn onClose ausgelöst wird? Warum kann ich oEvent nicht in meinem Bereich speichern?

Antwort

2

Event ist ein Modul, das Poolable implementiert, was bedeutet, dass Ereignisinit und reset zu implementieren hat, die („oEventPool“ intern) wird dann von seinem entsprechenden ObjectPool Beispiel genutzt werden, um die vorhandene Ereignisinstanz Wiederverwendung für die nächste Veranstaltung.

Das "nächste Ereignis" ist in unserem Fall das Ereignis "close", das vom Dialog ausgelöst wurde. Wie Sie bereits beobachten konnten, hat oEvent plötzlich nicht die ID "selectionChange" sondern "close". Dies liegt daran, dass die Event Instanz zurückgesetzt und erneut verwendet wurde. Und da oEvent nur eine Referenz (keine Kopie) ist und weil JS Call by Object-Sharing ist, ist es "geändert".

Die API-Referenz von ObjectPool erklärt, was es mit der Ereignisse Instanz tut:

(ObjectPool) führt eine Liste der freien Objekte des angegebenen Typs. Wenn sap.ui.base.ObjectPool.prototype.borrowObject aufgerufen wird, wird ein vorhandenes freies Objekt aus dem Pool genommen und für dieses Objekt die Methode init aufgerufen.

Wenn nicht mehr benötigt, sollte jedes geliehene Objekt durch Aufruf von #returnObject an den Pool zurückgegeben werden. Zu diesem Zeitpunkt wird die Methode reset für das Objekt aufgerufen, und das Objekt wird zur Liste der freien Objekte hinzugefügt.

Derzeit wird das (Ereignis-) Objekt als "no longer needed" when its handler is called betrachtet. Das Objekt wird also direkt nach onSelectionChange zurückgesetzt und erneut initialisiert, bevor onClose ausgelöst wird.

UI5 tut dies, so dass es keine Ereignis Instanzen erstellen und zerstören muss, um die Leistung zu verbessern. Dies ist eine aus der Object Pool Design Pattern (die auch often used in a game development ist) geliehene Praxis.


Was bedeutet das für uns als Anwendungsentwickler? Verlassen Sie sich nicht auf dasselbe Ereignisobjekt in einem anderen Handler. Nehmen Sie stattdessen die primitiven Werte aus dem Ereignisobjekt heraus und weisen Sie sie einer Variablen zu, damit wir sie später verwenden können.

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