Feature Control ermöglicht die dynamische Steuerung von UI-Elementen in Fiori-Anwendungen. Du kannst Felder, Aktionen und Operationen basierend auf dem Datenzustand oder Berechtigungen aktivieren, deaktivieren oder als Pflichtfelder markieren.
Static vs. Dynamic Feature Control
RAP unterscheidet zwischen statischem (deklarativem) und dynamischem (programmatischem) Feature Control:
| Aspekt | Static Feature Control | Dynamic Feature Control |
|---|---|---|
| Definition | In Behavior Definition | In Behavior Implementation |
| Auswertung | Kompilierzeit | Laufzeit |
| Kontext | Immer gleich | Instanz- oder global abhängig |
| Beispiel | field ( readonly ) TravelId | features: instance |
Static Feature Control
Statische Features werden direkt in der Behavior Definition deklariert:
define behavior for ZI_Travel alias Travelpersistent table ztravellock masterauthorization master ( instance )etag master LastChangedAt{ create; update; delete;
// Statische Feld-Features field ( readonly ) TravelId; " Immer schreibgeschützt field ( mandatory ) CustomerId; " Immer Pflichtfeld field ( readonly : update ) AgencyId; " Nur beim Update readonly field ( readonly ) CreatedBy, CreatedAt; " Admin-Felder}Dynamic Feature Control
Dynamische Features werden zur Laufzeit berechnet:
define behavior for ZI_Travel alias Travel{ // Operationen mit dynamischem Feature Control delete ( features: instance );
// Felder mit dynamischem Feature Control field ( features: instance ) Status, Description;
// Aktionen mit dynamischem Feature Control action ( features: instance ) acceptTravel result [1] $self; action ( features: instance ) rejectTravel result [1] $self;
// Global Feature Control aktivieren static features;}Instance Feature Control
Instance Feature Control ermöglicht die Steuerung von Features pro Instanz basierend auf deren Datenzustand.
Implementation
CLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler. PRIVATE SECTION. METHODS get_instance_features FOR INSTANCE FEATURES IMPORTING keys REQUEST requested_features FOR Travel RESULT result.ENDCLASS.
CLASS lhc_travel IMPLEMENTATION. METHOD get_instance_features. " Aktuelle Instanzdaten lesen READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( Status ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel) FAILED failed.
" Features pro Instanz setzen result = VALUE #( FOR ls_travel IN lt_travel LET lv_is_open = xsdbool( ls_travel-Status = 'O' ) lv_is_accepted = xsdbool( ls_travel-Status = 'A' ) IN ( %tky = ls_travel-%tky
" Delete nur bei Status 'Open' erlaubt %delete = COND #( WHEN lv_is_open = abap_true THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled )
" Felder je nach Status readonly oder editierbar %field-Status = COND #( WHEN lv_is_open = abap_true THEN if_abap_behv=>fc-f-unrestricted ELSE if_abap_behv=>fc-f-read_only ) %field-Description = COND #( WHEN lv_is_open = abap_true THEN if_abap_behv=>fc-f-unrestricted ELSE if_abap_behv=>fc-f-read_only )
" Accept-Action nur bei Status 'Open' %action-acceptTravel = COND #( WHEN lv_is_open = abap_true THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled )
" Reject-Action nur bei Status 'Accepted' %action-rejectTravel = COND #( WHEN lv_is_accepted = abap_true THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled ) ) ). ENDMETHOD.ENDCLASS.Feature-Konstanten
| Konstante | Typ | Beschreibung |
|---|---|---|
if_abap_behv=>fc-o-enabled | Operation | Operation aktiviert |
if_abap_behv=>fc-o-disabled | Operation | Operation deaktiviert |
if_abap_behv=>fc-f-read_only | Field | Schreibgeschützt |
if_abap_behv=>fc-f-mandatory | Field | Pflichtfeld |
if_abap_behv=>fc-f-unrestricted | Field | Keine Einschränkung |
if_abap_behv=>fc-f-mandatory_and_read_only | Field | Pflicht und readonly |
Global Feature Control
Global Feature Control steuert Features unabhängig von einzelnen Instanzen – typischerweise basierend auf Berechtigungen oder Systemzuständen.
Behavior Definition
define behavior for ZI_Travel alias Travel{ // Create mit Global Feature Control create ( features: global );
// Static Actions mit Global Feature Control static action ( features: global ) massUpdate; static action ( features: global ) importData;
// Global Features aktivieren static features;}Implementation
CLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler. PRIVATE SECTION. METHODS get_global_features FOR GLOBAL FEATURES IMPORTING REQUEST requested_features FOR Travel RESULT result.ENDCLASS.
CLASS lhc_travel IMPLEMENTATION. METHOD get_global_features. " Berechtigungsprüfung AUTHORITY-CHECK OBJECT 'Z_TRAVEL' ID 'ACTVT' FIELD '01'. " Create DATA(lv_has_create_auth) = xsdbool( sy-subrc = 0 ).
AUTHORITY-CHECK OBJECT 'Z_TRAVEL' ID 'ACTVT' FIELD '02'. " Change DATA(lv_has_change_auth) = xsdbool( sy-subrc = 0 ).
result = VALUE #( " Create nur mit Berechtigung %create = COND #( WHEN lv_has_create_auth = abap_true THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled )
" massUpdate nur mit Change-Berechtigung %action-massUpdate = COND #( WHEN lv_has_change_auth = abap_true THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled ) ). ENDMETHOD.ENDCLASS.Features für Standardoperationen
Create, Update, Delete
define behavior for ZI_Travel alias Travel{ // Static Feature Control create; " Immer erlaubt update; " Immer erlaubt delete ( features: instance ); " Dynamisch pro Instanz}METHOD get_instance_features. READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( Status ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel).
result = VALUE #( FOR ls_travel IN lt_travel ( %tky = ls_travel-%tky
" Update nur bei Status Open oder Draft %update = COND #( WHEN ls_travel-Status = 'O' OR ls_travel-Status = 'D' THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled )
" Delete nur bei Status Open %delete = COND #( WHEN ls_travel-Status = 'O' THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled ) ) ).ENDMETHOD.Zusammenspiel mit Authorization
Feature Control und Authorization ergänzen sich:
- Authorization: Berechtigungsprüfung – liefert Fehler bei unberechtigtem Zugriff
- Feature Control: UI-Steuerung – verhindert, dass Benutzer nicht erlaubte Aktionen sehen
CLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler. PRIVATE SECTION. METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION IMPORTING keys REQUEST requested_authorizations FOR Travel RESULT result.
METHODS get_instance_features FOR INSTANCE FEATURES IMPORTING keys REQUEST requested_features FOR Travel RESULT result.ENDCLASS.
CLASS lhc_travel IMPLEMENTATION. METHOD get_instance_authorizations. " Berechtigungsprüfung READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( AgencyId ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel).
LOOP AT lt_travel INTO DATA(ls_travel). " Prüfe Berechtigung für diese Agency AUTHORITY-CHECK OBJECT 'Z_AGENCY' ID 'AGENCY' FIELD ls_travel-AgencyId ID 'ACTVT' FIELD '02'.
DATA(lv_authorized) = xsdbool( sy-subrc = 0 ).
APPEND VALUE #( %tky = ls_travel-%tky %update = COND #( WHEN lv_authorized = abap_true THEN if_abap_behv=>auth-allowed ELSE if_abap_behv=>auth-unauthorized ) %delete = COND #( WHEN lv_authorized = abap_true THEN if_abap_behv=>auth-allowed ELSE if_abap_behv=>auth-unauthorized ) ) TO result. ENDLOOP. ENDMETHOD.
METHOD get_instance_features. " Feature Control: Basierend auf Status UND Berechtigung READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( Status AgencyId ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel).
LOOP AT lt_travel INTO DATA(ls_travel). " Berechtigung prüfen AUTHORITY-CHECK OBJECT 'Z_AGENCY' ID 'AGENCY' FIELD ls_travel-AgencyId ID 'ACTVT' FIELD '02'. DATA(lv_has_auth) = xsdbool( sy-subrc = 0 ).
" Kombination: Status Open UND Berechtigung DATA(lv_can_edit) = xsdbool( ls_travel-Status = 'O' AND lv_has_auth = abap_true ).
APPEND VALUE #( %tky = ls_travel-%tky %delete = COND #( WHEN lv_can_edit = abap_true THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled ) %field-Description = COND #( WHEN lv_can_edit = abap_true THEN if_abap_behv=>fc-f-unrestricted ELSE if_abap_behv=>fc-f-read_only ) ) TO result. ENDLOOP. ENDMETHOD.ENDCLASS.Mandatory-Felder dynamisch setzen
METHOD get_instance_features. READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( Status TravelType ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel).
result = VALUE #( FOR ls_travel IN lt_travel ( %tky = ls_travel-%tky
" CustomerID ist Pflicht bei Business-Reisen %field-CustomerId = COND #( WHEN ls_travel-TravelType = 'B' " Business THEN if_abap_behv=>fc-f-mandatory ELSE if_abap_behv=>fc-f-unrestricted )
" Approval ist Pflicht ab gewissem Betrag %field-ApproverId = COND #( WHEN ls_travel-TotalPrice > 5000 THEN if_abap_behv=>fc-f-mandatory ELSE if_abap_behv=>fc-f-unrestricted ) ) ).ENDMETHOD.Performance-Optimierung
Feature Control wird häufig aufgerufen. Optimiere die Implementierung:
METHOD get_instance_features. " 1. Nur benötigte Features berechnen CHECK requested_features-%delete = if_abap_behv=>mk-on OR requested_features-%action-acceptTravel = if_abap_behv=>mk-on OR requested_features-%field-Status = if_abap_behv=>mk-on.
" 2. Minimale Felder lesen READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( Status ) " Nur was benötigt wird WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel).
" 3. Effiziente Schleife result = VALUE #( FOR ls_travel IN lt_travel ( %tky = ls_travel-%tky %delete = COND #( WHEN ls_travel-Status = 'O' THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled ) " ... weitere Features ) ).ENDMETHOD.Best Practices
-
Konsistenz: Feature Control und Validierungen müssen konsistent sein – ein deaktiviertes Feld sollte nicht in einer Validation geprüft werden
-
IN LOCAL MODE: Verwende
IN LOCAL MODEum Authorization-Loops zu vermeiden -
Minimale Datenbankzugriffe: Lese nur die Felder, die du für die Feature-Entscheidung brauchst
-
Global vs. Instance: Nutze Global Feature Control für berechtigungsbasierte Features, Instance für datenbasierte
-
Requested Features prüfen: Berechne nur angeforderte Features zur Performance-Optimierung
-
Dokumentation: Dokumentiere die Feature-Logik, damit andere Entwickler verstehen, warum Felder/Aktionen wann verfügbar sind
Weiterführende Themen
- RAP Side Effects - Automatische UI-Updates
- RAP Authorization - Berechtigungsprüfungen
- RAP Actions und Functions - Geschäftslogik implementieren