Kategorien
SAP Schulung

Tipp: Multidimensionale Arrays PHP für UI5 Views

So etwas, sollte man vermeiden: Mehrfaches laden von Datensätzen in einem Kontext

Das mag im Schulungsumfeld „OK“ sein – Produktiv bedeutet das aber Umstand, Unübersichtlichkeit und Zeit. Schöner ist das bilden eines JSON Datensatzes. Das geht ganz einfach:

Einen Satz laden und durch den JSON Tree selektieren.

Kategorien
SAP Schulung

UI5: Attribute PL/pgSQL vs JScript

Da scheiden sich die Geister: Datenaggregation und das setzen der Properties eines UI5 Elements nach oder mit der SQL Abfrage? Eine Frage der Sicherheit und des Komforts. Beispiel unsere KPI Seite https://halsec.de

Die Daten für die Kurs Kacheln habe ich aus Basis von PL/pgSQL als Funktion realisiert. Postgresql übernimmt die Selektion der Daten und die Findung der Properties.

Der JSON Datensatz beinhaltet so alle nötigen Daten zur Darstellung der Kurs Kachel im UI5. So gestaltet sich das JavaScript im UI5 sehr einfach:

(Controller)
var anzeige1 = new sap.ui.model.json.JSONModel();
anzeige1.loadData(„https://halsec.de/fetch/ui5_eins.php?wo=USD“);
this.byId(„gt2“).setModel(anzeige1, „rates„);

(View)

<GenericTile id="gt2" class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="€ / US-Dollar" subheader="EZB Tagekurs" press="kltabelle2()">
<TileContent id="tc2" unit="USD 20d AVG" footer="">
<NumericContent id="nc1" value="{rates>/v_rate}" scale="Eu" valueColor="{rates>/v_stat}" indicator="{rates>/v_indi}" withMargin="false" />
</TileContent></GenericTile>

Die Kacheln, die die Temperatur anzeigen, sind JavaScript generiert. Der JSON Datensatz liefert eine Datenmenge, die innerhalb UI5 bewertet wird.

Das pro cedere im JavaScript stellt sich wie folgt dar:

(Controller)
var ui5ang2 = {anzeige: [{indi:“None“, status:“Neutral“}]};
oModel3.loadData(„https://halsec.de/fetch/tempBRI.php“);
anzeige5.setData(ui5ang2);

oModel3.attachRequestCompleted(function() {
var a = oModel3.getProperty(„/0/temo“);
var b = oModel3.getProperty(„/2/temo“);
a = parseInt(a);
b = parseInt(b);
if (a > b) {
anzeige5.setProperty(„/anzeige/0/indi“ , „Up“);
};
if(a < b) { anzeige5.setProperty(„/anzeige/0/indi“ , „Down“); }; if(a > 25 || a <= 0) { anzeige5.setProperty(„/anzeige/0/status“ , „Error“); }; if(a > 5 && a < 10) { anzeige5.setProperty(„/anzeige/0/status“ , „Critical“); }; if(a >= 10 && a <= 25) {
anzeige5.setProperty(„/anzeige/0/status“ , „Good“);
};
});

(View)

<GenericTile id="21" class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="Brilon" subheader="{bri>/0/abfrage}" press="kltabelle1()"> <TileContent id="tc21" unit="Temperatur" footer="DWD"> <NumericContent id="nc21" scale="C" value="{bri>/0/temo}" icon="sap-icon://temperature" valueColor="{brianzeige>/anzeige/0/status}" indicator="{brianzeige>/ </TileContent> </GenericTile>"
Kategorien
Randnotiz

Was läuft?

Neben der Entwicklung einer SAPUI5 Anwendung sowie einem SAP ABAP Projekt, lese ich mich in ein Langzeitprojekt ein. Programmierung auf IBM Servern in RGP. Eine Business-Anwendung soll um Free-RPG erweitert und Code geändert werden.

Haben sie auch spannende Aufgaben? Ich bin für Sie da!

Kategorien
SAP

UI5: Route und Variabeln

Eingrenzende Filterung oder Bindung in Listen und Tabellen sind häufige Szenarien die in UI5 Anwendungen. Wie kann das realisiert werden, besteht die Anwendung aus mehreren Views?

Eine Möglichkeit ist das speichern von Daten im Session Storage – aus Sicherheitsgründen eine nicht gern realisierte Lösung. Im Controller lassen sich Daten mit „sessionStorage.setItem(„Variable“, „Wert“);“ speichern und an anderer Stelle oder anderem Controller mit „var Variable2 = sessionStorage.getItem(„Variable“);“ gelesen werden.

Eine bessere Lösung ist das deklarieren von globalen Variabeln. Im Controller, ausserhalb einer Funktion, simpel „var Variable;“ vereinbaren. Nach Aufruf des Controllers ist die Variable global verfügbar.

Von SAP favorisiert, ist das arbeiten mit Routing und Targets. Werte werden mit dem Aufruf eines Controllers über das Routing „mitgegeben“. So kann im aufgerufenen View Daten nach Selektion durch Binding oder Filter eingeschränkt dargestellt werden.

Im View 1 (Link zum Beispiel) wählen wir einen Kunden aus, nach dessen Kundennummer (description) im View2 die in Relation stehende Daten gefiltert darsgestellt werden.

Im Controller wird Wert aus dem gewählten Listeneintrag gelesen

NavTo lädt entsprechenden Controller. Das geschieht über die im manifest.json vereinbarten Router und Targets:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
"routes": [
            {
                ...........................
            },
            {
                "name": "kunde",
                "pattern": "kunde",
                "target": [
                    "kunde"
                ]
            },
            {
                "name": "bst",
                "pattern": "bst",
                "target": [
                    "bst"
                ]
            },
            {
                "name": "bst",
                "pattern": "bst/description/{description}",
                "target": [
                    "bst"
                ]
            },              
            {
                "name": "cam",
                "pattern": "cam",
                "target": [
                    "cam"
                ]
            },
            {
                "name": "cam",
                "pattern": "cam/description/{description}",
                "target": [
                    "cam"
                ]
            }               
        ],
        "targets": {
            ..................................
            },
            "kunde": {
                "viewType": "XML",
                "viewName": "kunde"
            },
            "bst": {
                "viewType": "XML",
                "viewName": "bst"
            },
            "cam": {
                "viewType": "XML",
                "viewName": "cam"
            }

Es ist zu erkennen, wie die Variable „description“ über den Router im manifest quasi über die URL weiter gegeben wird. Wird der Controller des Views „bst“ aufgerufen wird, liest die Funktion „onInit“ den übergbenen Wert.

OnInit ruft _onRouteMatched auf, wenn Daten übergeben wurden
mit dem übergebenden Argument, wird ein Filter gesetzt

Wird im zweiten View, durch Klick auf einen Listeneintrag, weiter selektiert, muss die Route und das Target ebenfalls deklariert sein.

Weiter Selektion läuft nach dem selben Muster ab

In dem Beispiel navigieren wir nur durch drei Views. Die Möglichkeiten der Selektion sind natürlich frei verwendbar und zu kombinieren.

Kategorien
SAP

UI5: mehrfach JSON Model

Im Controller können beliebige JSON Model gebunden werden.

Die Model sind mit setModel(oModel,“XXXXX“) mit verschiedenen Namen gebunden. Im View lassen sich die Namen direkt ansprechen.

In dem Beispiel stelle ich Wetterdaten in einem einfachen Generic Tile dar. Die Wetterdaten werden von einem PHP Script aufbereitet – mit einfachem print out ist es nicht einmal ein gültiges JSON. UI5 ist in der Hinsicht unempfindlich.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
// Wetterdaten aus Postgres
$dbconn = pg_connect("host=localhost dbname=a user=b password=c")
    or die('Verbindungsaufbau fehlgeschlagen: ' . pg_last_error());
$query = 'select roh from orders order by id desc limit 1;';
$result = pg_query($query);
$line = pg_fetch_array($result, null, PGSQL_ASSOC);
$obj = json_decode($line['roh']);
// in Freeboard KPI genutzt
//case ("temp"):
//$such =  round($obj->main->temp - 273.15);
//break;
//case ("wind"):
//$such =  round($obj->wind->speed * 1.61);
//break;
//case ("aufgang"):
$dusk = date("H:i:s",$obj->sys->sunrise);
//break;
//case ("untergang"):
$dawn = date("H:i:s",$obj->sys->sunset);
//break;
// Handling Datum
// Thomas August 2019
$aWeekdayNamesDE = [
    'Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'
    ];
$aMonthNamesDE = [
    'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni',
        'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'
        ];
$dt = new DateTime();
//}
print('{"data":{ "dusk": "'.$dusk.'", "dawn": "'.$dawn.'", "day": "'.$aWeekdayNamesDE[$dt->format('w')].'", "month": "'.$aMonthNamesDE[$dt->format('n')-1].'", "kw": "'.$dt->format('W').'", "dayn": "'.$dt->format('d').'", "year": "'.$dt->format('Y').'"}}');
// Speicher freigeben
pg_free_result($result);
// Verbindung schließen
pg_close($dbconn);
?>

Ergebnis des PHP Scripts hier zum Beispiel: {„data“:{ „dusk“: „06:36:17“, „dawn“: „20:30:34“, „day“: „Mittwoch“, „month“: „August“, „kw“: „35“, „dayn“: „26“, „year“: „2020“}} und { „data“: [[0,19],[1,19],[2,19]]}