Feature Control permite el control dinámico de elementos UI en aplicaciones Fiori. Puedes activar, desactivar campos, acciones y operaciones o marcarlas como obligatorias basándote en el estado de los datos o permisos.
Static vs. Dynamic Feature Control
RAP distingue entre Feature Control estático (declarativo) y dinámico (programático):
| Aspecto | Static Feature Control | Dynamic Feature Control |
|---|---|---|
| Definición | En Behavior Definition | En Behavior Implementation |
| Evaluación | Tiempo de compilación | Tiempo de ejecución |
| Contexto | Siempre igual | Dependiente de instancia o global |
| Ejemplo | field ( readonly ) TravelId | features: instance |
Static Feature Control
Las características estáticas se declaran directamente en la Behavior Definition:
define behavior for ZI_Travel alias Travelpersistent table ztravellock masterauthorization master ( instance )etag master LastChangedAt{ create; update; delete;
// Features de campo estáticos field ( readonly ) TravelId; " Siempre solo lectura field ( mandatory ) CustomerId; " Siempre obligatorio field ( readonly : update ) AgencyId; " Solo lectura en update field ( readonly ) CreatedBy, CreatedAt; " Campos admin}Dynamic Feature Control
Las características dinámicas se calculan en tiempo de ejecución:
define behavior for ZI_Travel alias Travel{ // Operaciones con Feature Control dinámico delete ( features: instance );
// Campos con Feature Control dinámico field ( features: instance ) Status, Description;
// Acciones con Feature Control dinámico action ( features: instance ) acceptTravel result [1] $self; action ( features: instance ) rejectTravel result [1] $self;
// Activar Global Feature Control static features;}Instance Feature Control
Instance Feature Control permite controlar características por instancia basándose en su estado de datos.
Implementación
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. " Leer datos de instancia actual READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( Status ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel) FAILED failed.
" Establecer features por instancia 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 solo permitido con Status 'Open' %delete = COND #( WHEN lv_is_open = abap_true THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled )
" Campos readonly o editables según estado %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 solo con 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 solo con 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.Constantes de Feature
| Constante | Tipo | Descripción |
|---|---|---|
if_abap_behv=>fc-o-enabled | Operation | Operación activada |
if_abap_behv=>fc-o-disabled | Operation | Operación desactivada |
if_abap_behv=>fc-f-read_only | Field | Solo lectura |
if_abap_behv=>fc-f-mandatory | Field | Campo obligatorio |
if_abap_behv=>fc-f-unrestricted | Field | Sin restricción |
if_abap_behv=>fc-f-mandatory_and_read_only | Field | Obligatorio y readonly |
Global Feature Control
Global Feature Control controla características independientemente de instancias individuales - típicamente basado en permisos o estados del sistema.
Behavior Definition
define behavior for ZI_Travel alias Travel{ // Create con Global Feature Control create ( features: global );
// Static Actions con Global Feature Control static action ( features: global ) massUpdate; static action ( features: global ) importData;
// Activar Global Features static features;}Implementación
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. " Verificación de permisos 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 solo con permiso %create = COND #( WHEN lv_has_create_auth = abap_true THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled )
" massUpdate solo con permiso Change %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 para operaciones estándar
Create, Update, Delete
define behavior for ZI_Travel alias Travel{ // Static Feature Control create; " Siempre permitido update; " Siempre permitido delete ( features: instance ); " Dinámico por instancia}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 solo con Status Open o 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 solo con Status Open %delete = COND #( WHEN ls_travel-Status = 'O' THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled ) ) ).ENDMETHOD.Interacción con Authorization
Feature Control y Authorization se complementan:
- Authorization: Verificación de permisos - devuelve error en acceso no autorizado
- Feature Control: Control de UI - evita que usuarios vean acciones no permitidas
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. " Verificación de permisos 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). " Verificar permiso para esta 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: Basado en Status Y permisos 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). " Verificar permiso AUTHORITY-CHECK OBJECT 'Z_AGENCY' ID 'AGENCY' FIELD ls_travel-AgencyId ID 'ACTVT' FIELD '02'. DATA(lv_has_auth) = xsdbool( sy-subrc = 0 ).
" Combinación: Status Open Y permiso 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.Establecer campos obligatorios dinámicamente
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 es obligatorio en viajes de negocios %field-CustomerId = COND #( WHEN ls_travel-TravelType = 'B' " Business THEN if_abap_behv=>fc-f-mandatory ELSE if_abap_behv=>fc-f-unrestricted )
" Approval es obligatorio a partir de cierto monto %field-ApproverId = COND #( WHEN ls_travel-TotalPrice > 5000 THEN if_abap_behv=>fc-f-mandatory ELSE if_abap_behv=>fc-f-unrestricted ) ) ).ENDMETHOD.Optimización de rendimiento
Feature Control se llama frecuentemente. Optimiza la implementación:
METHOD get_instance_features. " 1. Calcular solo features necesarios 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. Leer campos mínimos READ ENTITIES OF zi_travel IN LOCAL MODE ENTITY Travel FIELDS ( Status ) " Solo lo necesario WITH CORRESPONDING #( keys ) RESULT DATA(lt_travel).
" 3. Bucle eficiente 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 ) " ... más features ) ).ENDMETHOD.Mejores prácticas
-
Consistencia: Feature Control y Validations deben ser consistentes - un campo desactivado no debería verificarse en una Validation
-
IN LOCAL MODE: Usa
IN LOCAL MODEpara evitar loops de Authorization -
Accesos mínimos a base de datos: Lee solo los campos que necesitas para la decisión de features
-
Global vs. Instance: Usa Global Feature Control para features basados en permisos, Instance para basados en datos
-
Verificar Requested Features: Calcula solo features solicitados para optimización de rendimiento
-
Documentación: Documenta la lógica de features para que otros desarrolladores entiendan cuándo están disponibles campos/acciones
Temas relacionados
- RAP Side Effects - Actualizaciones automáticas de UI
- RAP Authorization - Verificaciones de permisos
- RAP Actions y Functions - Implementar lógica de negocio