Side Effects in RAP definieren, welche UI-Elemente aktualisiert werden sollen, wenn sich Feldwerte ändern oder Aktionen ausgeführt werden. Sie sorgen für eine reaktive Benutzeroberfläche ohne manuelles Neuladen.
Wofür Side Effects?
Side Effects beantworten Fragen wie:
- Welche Felder müssen aktualisiert werden, wenn sich der Preis ändert?
- Welche Bereiche der UI müssen nach einer Aktion neu geladen werden?
- Wie werden berechnete Felder automatisch aktualisiert?
Typische Anwendungsfälle
| Szenario | Trigger | Betroffene Felder |
|---|---|---|
| Preisberechnung | Menge, Einzelpreis | Gesamtpreis |
| Datumsberechnung | Start- oder Enddatum | Dauer, Arbeitstage |
| Währungsumrechnung | Währung | Alle Betragsfelder |
| Statusänderung | Action ausführen | Status, Verfügbarkeit |
Side Effects in der Behavior Definition
Side Effects werden deklarativ in der Behavior Definition festgelegt:
managed implementation in class zbp_i_travel unique;strict ( 2 );
define behavior for ZI_Travel alias Travelpersistent table ztravellock masterauthorization master ( instance )etag master LastChangedAt{ create; update; delete;
// Side Effects Block side effects { // Field-Level Side Effects field BeginDate affects field Duration; field EndDate affects field Duration;
// Action-Level Side Effects action calculatePrice affects field TotalPrice, field Currency;
// Determination Side Effects determine action Prepare affects field Status; }}Field-Level Side Effects
Field-Level Side Effects definieren, welche Felder aktualisiert werden, wenn ein bestimmtes Feld geändert wird.
Einfacher Field Side Effect
side effects{ // Wenn BeginDate sich ändert, aktualisiere Duration field BeginDate affects field Duration;
// Wenn EndDate sich ändert, aktualisiere Duration field EndDate affects field Duration;}Mehrere Trigger-Felder
side effects{ // Mehrere Felder triggern die gleiche Aktualisierung field ( BeginDate, EndDate ) affects field Duration;
// Preis-Berechnung bei Mengen- oder Preisänderung field ( Quantity, UnitPrice ) affects field TotalPrice;}Mehrere betroffene Felder
side effects{ // Ein Trigger-Feld beeinflusst mehrere Zielfelder field Quantity affects field TotalPrice, field TaxAmount, field NetPrice;
// Währungsänderung beeinflusst alle Betragsfelder field CurrencyCode affects field TotalPrice, field TaxAmount, field Discount;}$self - Die gesamte Instanz
Mit $self wird die gesamte Instanz als betroffen markiert:
side effects{ // Währungsänderung: Alle Felder neu laden field CurrencyCode affects $self;
// Kundenänderung: Gesamte Instanz aktualisieren field CustomerId affects $self;}Action-Level Side Effects
Action-Level Side Effects definieren, welche Felder nach einer Aktion aktualisiert werden.
define behavior for ZI_Travel alias Travel{ // Aktionen definieren action calculatePrice result [1] $self; action applyDiscount result [1] $self; action setStatus result [1] $self;
side effects { // Nach Preisberechnung diese Felder aktualisieren action calculatePrice affects field TotalPrice, field TaxAmount;
// Nach Rabatt-Anwendung action applyDiscount affects field TotalPrice, field DiscountAmount;
// Statusänderung beeinflusst Status-Feld action setStatus affects field Status; }}Action mit komplexen Side Effects
side effects{ // Action beeinflusst mehrere Bereiche action recalculateAll affects field TotalPrice, field TaxAmount, field NetPrice, field Currency, entity _Bookings; // Auch Assoziationen
// Action beeinflusst gesamte Entität action copyFromTemplate affects $self;}Determination Side Effects
Wenn Determinations ausgeführt werden, können Side Effects die UI über berechnete Werte informieren.
Behavior Definition
define behavior for ZI_Travel alias Travel{ // Determination für Preisberechnung determination calculateTotalPrice on modify { field Quantity; field UnitPrice; }
// Determination für Status determination setInitialStatus on modify { create; }
side effects { // Wenn calculateTotalPrice auf Quantity-Änderung ausgeführt wird determine action calculateTotalPrice executed on field Quantity affects field TotalPrice;
// Wenn calculateTotalPrice auf UnitPrice-Änderung ausgeführt wird determine action calculateTotalPrice executed on field UnitPrice affects field TotalPrice; }}Vollständiges Beispiel mit Determination
managed implementation in class zbp_i_travel unique;strict ( 2 );
define behavior for ZI_Travel alias Travelpersistent table ztravel{ create; update; delete;
// Determinations determination calculateDuration on modify { field BeginDate; field EndDate; } determination calculatePrice on modify { field Quantity; field UnitPrice; field CurrencyCode; }
side effects { // Duration-Berechnung determine action calculateDuration executed on field BeginDate affects field Duration; determine action calculateDuration executed on field EndDate affects field Duration;
// Preis-Berechnung determine action calculatePrice executed on field Quantity affects field TotalPrice, field TaxAmount; determine action calculatePrice executed on field UnitPrice affects field TotalPrice, field TaxAmount; determine action calculatePrice executed on field CurrencyCode affects field TotalPrice, field TaxAmount, field Currency; }}Implementation der Determination
CLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler. PRIVATE SECTION. METHODS calculateDuration FOR DETERMINE ON MODIFY IMPORTING keys FOR Travel~calculateDuration.
METHODS calculatePrice FOR DETERMINE ON MODIFY IMPORTING keys FOR Travel~calculatePrice.ENDCLASS.
CLASS lhc_travel IMPLEMENTATION. METHOD calculateDuration. READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( BeginDate EndDate ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel).
MODIFY ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel UPDATE FIELDS ( Duration ) WITH VALUE #( FOR ls_travel IN lt_travel WHERE ( BeginDate IS NOT INITIAL AND EndDate IS NOT INITIAL ) ( %tky = ls_travel-%tky Duration = ls_travel-EndDate - ls_travel-BeginDate ) ) REPORTED reported. ENDMETHOD.
METHOD calculatePrice. READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( Quantity UnitPrice CurrencyCode ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel).
MODIFY ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel UPDATE FIELDS ( TotalPrice TaxAmount Currency ) WITH VALUE #( FOR ls_travel IN lt_travel LET lv_total = ls_travel-Quantity * ls_travel-UnitPrice lv_tax = lv_total * '0.19' IN ( %tky = ls_travel-%tky TotalPrice = lv_total TaxAmount = lv_tax Currency = ls_travel-CurrencyCode ) ) REPORTED reported. ENDMETHOD.ENDCLASS.Side Effects mit Assoziationen
Side Effects können auch Assoziationen betreffen:
define behavior for ZI_Travel alias Travel{ association _Bookings { create; }
side effects { // Änderungen an Bookings beeinflussen Travel field _Bookings affects field TotalPrice, field BookingCount;
// Währungsänderung in Travel beeinflusst alle Bookings field CurrencyCode affects entity _Bookings; }}
define behavior for ZI_Booking alias Booking{ association _Travel;
side effects { // Preis in Booking beeinflusst Gesamtpreis in Travel field Price affects field _Travel.TotalPrice; }}Hierarchische Side Effects
define behavior for ZI_Travel alias Travel{ side effects { // Alle Bookings aktualisieren wenn sich Währung ändert field CurrencyCode affects entity _Bookings, entity _Passengers;
// Nach Copy-Action alle Child-Entitäten neu laden action copyWithDetails affects $self, entity _Bookings, entity _Passengers; }}Target-Felder und $self
Einzelne Zielfelder
side effects{ field Quantity affects field TotalPrice;}Mehrere Zielfelder
side effects{ field Quantity affects field TotalPrice, field TaxAmount, field NetPrice;}Gesamte Entität ($self)
side effects{ // Bei Statusänderung: Komplette Instanz neu laden field Status affects $self;
// Bei Kopie: Alles aktualisieren action copy affects $self;}Entity (Assoziationen)
side effects{ // Child-Entitäten aktualisieren field CurrencyCode affects entity _Bookings;
// Parent-Entität aktualisieren field BookingPrice affects entity _Travel;}Vollständiges Beispiel
managed implementation in class zbp_i_travel unique;strict ( 2 );
define behavior for ZI_Travel alias Travelpersistent table ztraveldraft table zdraft_travellock master total etag LastChangedAtauthorization master ( instance )etag master LastChangedAt{ create; update; delete;
// Felder field ( readonly ) TravelId, CreatedBy, CreatedAt; field ( mandatory ) CustomerId;
// Assoziationen association _Bookings { create; }
// Determinations determination calculateDuration on modify { field BeginDate; field EndDate; } determination calculateTotalPrice on modify { field _Bookings; } determination setInitialStatus on modify { create; }
// Actions action ( features: instance ) acceptTravel result [1] $self; action recalculatePrice result [1] $self;
// Side Effects side effects { // Field-Level field BeginDate affects field Duration, field DaysUntilStart; field EndDate affects field Duration; field CustomerId affects field CustomerName, field CustomerRating;
// Währung beeinflusst alle Betragsfelder field CurrencyCode affects field TotalPrice, field TaxAmount, entity _Bookings;
// Determination Side Effects determine action calculateDuration executed on field BeginDate affects field Duration; determine action calculateDuration executed on field EndDate affects field Duration; determine action calculateTotalPrice executed on field _Bookings affects field TotalPrice, field BookingCount;
// Action Side Effects action acceptTravel affects field Status, field ApprovedAt, field ApprovedBy; action recalculatePrice affects field TotalPrice, field TaxAmount, entity _Bookings; }}
define behavior for ZI_Booking alias Bookingpersistent table zbookingdraft table zdraft_bookinglock dependent by _Travelauthorization dependent by _Traveletag master LastChangedAt{ create; update; delete;
association _Travel;
side effects { // Preis-Änderung in Booking aktualisiert Travel-Summe field Price affects field _Travel.TotalPrice; }}Best Practices
-
Minimale Side Effects: Definiere nur die wirklich benötigten Side Effects – zu viele können die Performance beeinträchtigen
-
Spezifische Felder statt $self: Nutze $self nur, wenn wirklich die gesamte Entität betroffen ist
-
Determination + Side Effect: Kombiniere Determinations mit Side Effects für automatische Berechnungen
-
Bidirektionale Assoziationen: Achte bei Parent-Child-Beziehungen auf korrekte Richtung der Side Effects
-
Performance: Side Effects lösen UI-Requests aus – teste die Performance bei komplexen Szenarien
-
Konsistenz: Stelle sicher, dass die Side Effect-Definitionen mit der tatsächlichen Logik übereinstimmen
" RICHTIG: Side Effect passt zur Determinationdetermination calculateTotal on modify { field Quantity; field Price; }side effects{ determine action calculateTotal executed on field Quantity affects field TotalPrice; determine action calculateTotal executed on field Price affects field TotalPrice;}
" FALSCH: Side Effect ohne entsprechende Berechnungside effects{ field Quantity affects field TotalPrice; " Wer berechnet TotalPrice?}Weiterführende Themen
- RAP Feature Control - Dynamische UI-Steuerung
- RAP Determinations & Validations - Automatische Berechnungen
- RAP Draft Handling - Zwischenspeicherung