Le Feature Control permet le contrôle dynamique des éléments UI comme les champs, actions et opérations en fonction de l’état actuel des données. Les Side Effects assurent les mises à jour automatiques de l’UI lorsque les valeurs des champs changent.
Pourquoi le Feature Control ?
Le Feature Control répond à des questions telles que :
- L’utilisateur peut-il supprimer cette instance ?
- Ce champ doit-il être en lecture seule ?
- Cette action est-elle disponible pour le statut actuel ?
- L’utilisateur peut-il modifier les associations ?
Instance vs. Global Feature Control
| Aspect | Instance Feature Control | Global Feature Control |
|---|---|---|
| Portée | Par instance | Pour toutes les instances |
| Évaluation | Pour chaque instance individuellement | Une fois pour l’entité |
| Cas d’usage | Fonctionnalités dépendantes du statut | Fonctionnalités dépendantes des autorisations |
| Performance | Plus élevée (n appels) | Plus faible (1 appel) |
| Exemple | ”Annuler uniquement si statut Ouvert" | "Create uniquement avec autorisation” |
Behavior Definition avec Feature Control
Les Features sont déclarées dans la Behavior Definition :
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;}Options de Feature
| Déclaration | Signification |
|---|---|
features: instance | Dynamique par instance |
features: global | Dynamique global (pour static actions) |
readonly | Toujours en lecture seule |
mandatory | Champ obligatoire |
readonly:update | En lecture seule uniquement lors de la mise à jour |
Implémentation d’Instance Feature Control
La méthode get_instance_features détermine les Features par instance :
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.Constantes de Feature
| Constante | Type | Signification |
|---|---|---|
if_abap_behv=>fc-o-enabled | Operation | Activé |
if_abap_behv=>fc-o-disabled | Operation | Désactivé |
if_abap_behv=>fc-f-read_only | Field | Lecture seule |
if_abap_behv=>fc-f-mandatory | Field | Obligatoire |
if_abap_behv=>fc-f-unrestricted | Field | Aucune restriction |
if_abap_behv=>fc-f-mandatory_and_read_only | Field | Obligatoire et readonly |
Global Feature Control
Le Global Feature Control contrôle les Features indépendamment des instances individuelles :
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 avec 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 : Mises à jour automatiques de l’UI
Les Side Effects définissent quelles parties de l’UI doivent être actualisées lorsque les valeurs des champs changent.
Side Effects dans la 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 pour les associations
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 pour les 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; }}Exemples combinés
Champs et actions dépendants du statut
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 avec 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; }}Dépendances de champs dans la Projection
Dans la Projection, des annotations UI supplémentaires peuvent être définies :
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}Bonnes pratiques
-
Attention à la performance : Instance Feature Control est appelé pour chaque instance. Minimisez les accès à la base de données.
-
Utiliser READ ENTITIES : Utilisez
IN LOCAL MODEpour éviter les vérifications d’autorisation. -
Logique cohérente : Assurez-vous que Feature Control et validations sont cohérents.
-
Utiliser Side Effects de manière ciblée : Trop de Side Effects peuvent affecter la performance.
-
Vérifier les Features demandées : Calculer uniquement les Features demandées :
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.- Features globales pour les autorisations : Utilisez Global Feature Control pour les restrictions basées sur les autorisations.
Sujets avancés
- RAP Basics - Fondamentaux du RESTful ABAP Programming Model
- Draft Handling in RAP - Sauvegarde temporaire avec Drafts
- RAP Actions et Functions - Implémenter la logique métier