Feature Control ermöglicht die dynamische Steuerung von UI-Elementen wie Feldern, Aktionen und Operationen basierend auf dem aktuellen Datenzustand. Side Effects sorgen für automatische UI-Updates, wenn sich Feldwerte ändern.
Wofür Feature Control?
Feature Control beantwortet Fragen wie:
- Darf der Benutzer diese Instanz löschen?
- Soll dieses Feld schreibgeschützt sein?
- Ist diese Aktion für den aktuellen Status verfügbar?
- Darf der Benutzer die Assoziationen ändern?
Instance vs. Global Feature Control
| Aspekt | Instance Feature Control | Global Feature Control |
|---|---|---|
| Geltungsbereich | Pro Instanz | Für alle Instanzen |
| Auswertung | Bei jeder Instanz einzeln | Einmal für die Entität |
| Anwendungsfall | Statusabhängige Features | Berechtigungsabhängige Features |
| Performance | Höher (n Aufrufe) | Niedriger (1 Aufruf) |
| Beispiel | ”Stornieren nur bei Status Open" | "Create nur mit Berechtigung” |
Behavior Definition mit Feature Control
Die Features werden in der Behavior Definition deklariert:
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 ( features: instance );
// Felder mit Feature Control field ( readonly ) TravelID; field ( features: instance ) Status, Description;
// Aktionen mit Feature Control action ( features: instance ) cancel; action ( features: instance ) accept;
// Globales Feature Control für Create static features;}Feature-Optionen
| Deklaration | Bedeutung |
|---|---|
features: instance | Dynamisch pro Instanz |
features: global | Dynamisch global (bei static actions) |
readonly | Immer schreibgeschützt |
mandatory | Pflichtfeld |
readonly:update | Nur beim Update schreibgeschützt |
Instance Feature Control Implementation
Die Methode get_instance_features bestimmt die Features pro Instanz:
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 Daten lesen READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( Status BeginDate ) WITH CORRESPONDING #( keys ) RESULT DATA(travels).
" Features pro Instanz setzen result = VALUE #( FOR travel IN travels LET is_open = COND #( WHEN travel-Status = 'O' THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled ) is_accepted = COND #( WHEN travel-Status = 'A' THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled ) is_readonly = COND #( WHEN travel-Status <> 'O' THEN if_abap_behv=>fc-f-read_only ELSE if_abap_behv=>fc-f-unrestricted ) IN ( %tky = travel-%tky " Operations %delete = is_open " Fields %field-Status = is_readonly %field-Description = is_readonly " Actions %action-cancel = is_open %action-accept = is_open ) ). ENDMETHOD.ENDCLASS.Feature-Konstanten
| Konstante | Typ | Bedeutung |
|---|---|---|
if_abap_behv=>fc-o-enabled | Operation | Aktiviert |
if_abap_behv=>fc-o-disabled | 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:
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 für Create DATA(has_create_auth) = check_create_authorization( ).
" Prüfen ob heute ein Arbeitstag ist DATA(is_workday) = check_workday( ).
result = VALUE #( " Create nur mit Berechtigung %create = COND #( WHEN has_create_auth = abap_true THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled ) " Static Action nur an Arbeitstagen %action-massUpdate = COND #( WHEN is_workday = abap_true THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled ) ). ENDMETHOD.ENDCLASS.Static Actions mit Feature Control
define behavior for ZI_Travel alias Travel{ // Static Action mit Global Feature Control static action ( features: global ) massUpdate result [1] $self; static action ( features: global ) generateReport;
// Reguläre Features static features;}Side Effects: Automatische UI-Updates
Side Effects definieren, welche Teile der UI aktualisiert werden sollen, wenn sich Feldwerte ändern.
Side Effects in der Behavior Definition
define behavior for ZI_Travel alias Travel{ // Side Effect: Wenn BeginDate oder EndDate sich ändert, berechne Duration side effects { field BeginDate affects field Duration; field EndDate affects field Duration;
// Mehrere Felder beeinflussen ein Zielfeld field ( BeginDate, EndDate ) affects field Duration, field TotalPrice;
// Feld beeinflusst gesamte Entität field Currency affects entity;
// Determination triggert Side Effect determine action calculatePrice executed on field BeginDate affects field TotalPrice; }}Side Effects für Assoziationen
define behavior for ZI_Travel alias Travel{ side effects { // Änderungen an Child-Entitäten beeinflussen Parent field _Bookings affects field TotalPrice;
// Feld in Parent beeinflusst Children field Currency affects entity _Bookings; }}Side Effects für Actions
define behavior for ZI_Travel alias Travel{ action recalculate;
side effects { // Nach Aktion werden diese Felder aktualisiert action recalculate affects field TotalPrice, field Status;
// Aktion beeinflusst gesamte Entität und Assoziationen action copyTravel affects entity, entity _Bookings; }}Kombinierte Beispiele
Status-abhängige Felder und Aktionen
METHOD get_instance_features. READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( Status TravelID ) WITH CORRESPONDING #( keys ) RESULT DATA(travels).
result = VALUE #( FOR travel IN travels ( %tky = travel-%tky
" Status Open: Alles editierbar %field-BeginDate = COND #( WHEN travel-Status = 'O' THEN if_abap_behv=>fc-f-unrestricted ELSE if_abap_behv=>fc-f-read_only ) %field-EndDate = COND #( WHEN travel-Status = 'O' THEN if_abap_behv=>fc-f-unrestricted ELSE if_abap_behv=>fc-f-read_only ) %field-CustomerID = COND #( WHEN travel-Status = 'O' THEN if_abap_behv=>fc-f-mandatory ELSE if_abap_behv=>fc-f-read_only )
" Delete nur bei Status Open %delete = COND #( WHEN travel-Status = 'O' THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled )
" Accept nur bei Status Open %action-accept = COND #( WHEN travel-Status = 'O' THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled )
" Reject nur bei Status Accepted %action-reject = COND #( WHEN travel-Status = 'A' THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled ) ) ).ENDMETHOD.Side Effects mit Determination
define behavior for ZI_Travel alias Travel{ // Determination für Preisberechnung determination calculatePrice on modify { field BeginDate; field EndDate; }
side effects { // Wenn Determination ausgeführt wird, aktualisiere TotalPrice in UI determine action calculatePrice executed on field BeginDate affects field TotalPrice, field Currency; determine action calculatePrice executed on field EndDate affects field TotalPrice; }}Field-Abhängigkeiten in der Projection
In der Projection können zusätzliche UI-Annotationen gesetzt werden:
define root view entity ZC_Travel provider contract transactional_query as projection on ZI_Travel{ @UI.hidden: true key TravelUUID,
@UI.identification: [{ position: 10 }] @UI.lineItem: [{ position: 10 }] TravelID,
@UI.identification: [{ position: 20, criticality: 'StatusCriticality' }] Status,
// Dynamische Sichtbarkeit über Hidden-Binding @UI.hidden: 'HideInternalNote' InternalNote,
// Calculated Field für Criticality case Status when 'O' then 3 " Green when 'A' then 2 " Yellow when 'X' then 1 " Red end as StatusCriticality}Best Practices
-
Performance beachten: Instance Feature Control wird für jede Instanz aufgerufen. Minimiere Datenbankzugriffe.
-
READ ENTITIES verwenden: Nutze
IN LOCAL MODEum Berechtigungsprüfungen zu vermeiden. -
Konsistente Logik: Stelle sicher, dass Feature Control und Validierungen konsistent sind.
-
Side Effects gezielt einsetzen: Zu viele Side Effects können die Performance beeinträchtigen.
-
Requested Features prüfen: Nur angeforderte Features berechnen:
METHOD get_instance_features. " Nur berechnen wenn angefordert CHECK requested_features-%delete = if_abap_behv=>mk-on OR requested_features-%action-cancel = if_abap_behv=>mk-on.
" ... Feature-BerechnungENDMETHOD.- Globale Features für Berechtigungen: Nutze Global Feature Control für berechtigungsbasierte Einschränkungen.
Weiterführende Themen
- RAP Basics - Grundlagen des RESTful ABAP Programming Model
- Draft Handling in RAP - Zwischenspeicherung mit Drafts
- RAP Actions und Functions - Geschäftslogik implementieren