Singleton mit Fiori

Zugriff von Models aus anderen Views? Einsatz von Singleton-Klassen im SAPUI5-Kontext

Bist du an einem Punkt angekommen, an dem du ein Model oder ein Control benötigst, das sich aber in einer anderen View befinden?

Wenn ja, dann bist du hier genau richtig! Denn auch ich bin auf dieses Problem gestoßen und möchte dir zeigen wie ich es gelöst habe.

 

Master-Detail App

Mein Ausgangspunkt ist in diesem Beispiel eine Master-Detail App.
Ich befinde mich gerade im Kontext des Master.Controllers und benötige ein Property, dass sich in im sogenannten “detailView”-Model befindet, welches jedoch lediglich auf die Detail-Page gebunden ist.
Mein erster Gedanke ist der Folgende:

Master.controller.js 
...
onSelectionChange: function(oEvent){
var oModel = this.getModel("detailView");
oModel.getProperty("bEdit");
}, ...

Sieht auf den ersten Blick ganz gut aus. Die Web IDE meckert nicht.

Doch in der Konsole kommt folgende Fehlermeldung.

Fehlermeldung in der Konsole

Anhand der Fehlermeldung wurde mir sofort klar, dass ich innerhalb des Master.Controller nicht das gewünschte Model aufrufen kann.
Sinngemäß suche ich auf der Master-Ebene vergebens nach dem Model “detailView”. Da ist es verständlich, dass die Konsole keine Property erkennt… Der Controller findet ja nicht mal das Model!

Um nun dieses Problem zu lösen zeige ich mit Hilfe von simulierten Klassen, wie du dir ganz leicht andere Models holst.

Ich beginne mit dem Erstellen einer Klasse und erweitere diese mit der Klasse “sap.ui.base.Object”. Meine Klasse entspricht der typischen Funktionalität eines sogenannten Singleton. Ein solches Singleton funktioniert genauso wie in der JAVA Entwicklung. Die Klasse wird aufgerufen, wenn ein Objekt der Klasse erstellt wird. Wie in jeder anderen Sprache können auch Methoden in der Klasse erstellt werden. Anstatt einer statischen Klasse, gebe ich die Funktion getInstance() zurück. Die Funktion erstellt nur beim ersten Mal eine neue Instanz der Klasse. Mit der IF-Abfrage stelle ich fest, ob eine Instanz bereits erzeugt wurde. Die “instance”-Variable erstelle ich, um die aktuelle Instanz festzuhalten.
Des Weiteren implementiere ich in der erweiterten Object-Klasse einen Konstruktor, sowie eine Getter- und Setter- Funktion, um so später den Zugriff und die Registrierung des gewünschten Models zu gewährleisten.

...NEW acando/TamsApp/Utils/UIHelper.js...
sap.ui.define([
	"sap/ui/base/Object"
], function (Object) {
	"use strict";
	var instance;
	var services = Object.extend("be.wl.objects.model.services", {
		constructor: function () {
			// this.controllerDetailView = null;
		},
		setControllerDetailView: function (oController) {
			this.controllerDetailView = oController;
		},
		getControllerDetailView: function () {
			return this.controllerDetailView;
		}
	});
	return {
		getInstance: function () {
			if (!instance) {
				instance = new services();
			}
			return instance;
		}
	};
});

Nun kann ich in meinem gewünschten Controller im UI.Helper registrieren.

Detail.controller.js
sap.ui.define([
...
"acando/TamsApp/Utils/UIHelper"
], function (BaseController, JSONModel, formatter, MessageBox, MessageToast, UIHelper) {
	"use strict";

return BaseController.extend("acando.TamsApp.controller.Detail", {

onInit: function () {
UIHelper.getInstance().setControllerDetailView(this);
...
},

Im Master.controller.js kann ich die zuvor registrierte Instanz mit Hilfe der Helper-Singleton-Klasse holen.

Master.controller.js
sap.ui.define([
	"acando/TamsApp/controller/BaseController",
	"sap/ui/model/json/JSONModel",
	"sap/ui/model/Filter",
	"sap/ui/model/FilterOperator",
	"sap/m/GroupHeaderListItem",
	"sap/ui/Device",
	"acando/TamsApp/model/formatter",
	"sap/m/MessageBox",
	"acando/TamsApp/Utils/UIHelper"
], function (BaseController, JSONModel, Filter, FilterOperator, GroupHeaderListItem, Device, formatter, MessageBox,UIHelper) {
	"use strict";
	
return BaseController.extend("acando.TamsApp.controller.Master", {
...
var oView = UIHelper.getInstance().getControllerDetailView();
....

Wenn ich in meiner Funktion einen Debugger setze und die Schritte in der Konsole verfolge, sehe ich folgende Ergebnisse:

Mit Hilfe des Singleton konnte ich nun auch auf andere Views zugreifen, die sich an diesem zuvor registriert haben. Im UI5 Kontext ist dies eine saubere Lösung um Models und deren Properties View-übergreifend zu lesen und zu verändern.
Wenn du weitere Informationen benötigst oder dir der Blog gefallen hat, schreibe doch einfach einen kurzen Kommentar. Schau dir auch unsere weiteren Artikel an, wenn du mehr über Fiori und SAPUI5 erfahren möchtest.

Du hast Lust auf einen coolen, abwechslungsreichen Job?
Arbeite als SAPUI5-Enwickler bei Acando!

Über den Autor

Cong Tam Nguyen

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

27 − 25 =