原创 3号技师-阿宇 [ 建广技师 ](javascript:void\(0\);)
经过这么多年的发展,Fiori日益成熟和完善,目前主要分为两种开发方向 freeStyle 和 elements
开发。自从S4问世以来,一个重要的原则就simple,所以在基本的UI5基础上出现了smart control 这种概念;开发重心向后端转移,通过
gateway + annotation 混合方式降低UI开发难度达到快速开发的目的。随着敏捷开发和low code思潮的流行,加上愈发强大的CDS,
由smart control
进化出来的elements开发应运而生。此时fiori的开发已经极简化,开发人员从复杂的UI开发中解脱出来,专注于后端逻辑的实现,打破前端开发壁垒,促进常规ABAP开发转型和提升。
由于近些年的快速发展,目前看到的elements 应用又可以细分,如图。
下面用一个完整的DEMO介绍基于unmanaged 类型的elements 应用的开发。 **1.选择数据表(SBOOK),也可自行创建**
**2.ADT中创建CDS,并添加annotation**
@AbapCatalog.sqlViewName: 'ZVBOOK'@AbapCatalog.compiler.compareFilter: true@AbapCatalog.preserveKey: true@AccessControl.authorizationCheck: #NOT_REQUIRED@EndUserText.label: 'FOR SBOOK'@Search.searchable : true
@UI: { headerInfo: { typeName: 'Booking', typeNamePlural: 'Bookings', title: { type: #STANDARD, value: 'Booking' } }}define root view ZIBOOK as select from sbook as BOOK association [0..*] to I_Currency as _Currency on $projection.CurrencyCode = _Currency.Currency or $projection.LocalCurrency = _Currency.Currency { @UI.facet: [{ id: 'Booking', purpose: #STANDARD, type: #IDENTIFICATION_REFERENCE, label: 'Booking info', position: 10 }] @UI:{ lineItem: [ {position: 10, importance: #HIGH, label: 'Airline Code'} ], identification: [ { position: 20, label: 'Airline Code'}], selectionField: {position: 10, element: 'carrid'} } key carrid, @UI:{ lineItem: [ {position: 20, importance: #HIGH, label: 'Flight Connection Number'} ], identification: [ { position: 10, label: 'Flight Connection Number'}], selectionField: {position: 10, element: 'connid'} } key connid, @UI:{ lineItem: [ {position: 30, importance: #HIGH, label: 'Flight date'} ], identification: [ { position: 30, label: 'Flight date'}], selectionField: {position: 10, element: 'fldate'} } @Search.defaultSearchElement: true key fldate, @UI:{ lineItem: [ {position: 40, importance: #HIGH, label: 'Booking number'} ], identification: [ { position: 40, label: 'Booking number'}] } key bookid, @UI:{ lineItem: [ {position: 50, importance: #HIGH, label: 'Name of the Passenger'} ], identification: [ { position: 50, label: 'Name of the Passenger'}], selectionField: {position: 10, element: 'passname'} } @Search.defaultSearchElement: true @Search.fuzzinessThreshold: 0.6 passname, @UI:{ lineItem: [ {position: 60, importance: #HIGH, label: 'Form of address'} ], identification: [ { position: 60, label: 'Form of address'}] } passform, @UI:{ identification: [ { position: 70, label: 'Booking price in foreign currency'}] } @Semantics.amount.currencyCode: 'CurrencyCode' forcuram, @UI:{ identification: [ { position: 80, label: 'Payment currency', hidden: true}] } @Semantics.currencyCode: true @Consumption.valueHelpDefinition: [ { entity: { name: 'I_Currency', element: 'Currency' } } ] forcurkey as CurrencyCode, @UI:{ lineItem: [ {position: 70, importance: #HIGH, label: 'Price of booking in local currency'} ], identification: [ { position: 90, label: 'Price of booking in local currency'}] } @Semantics.amount.currencyCode: 'LocalCurrency' loccuram, /*@UI:{ lineItem: [ {position: 80, label: 'Local currency', hidden: true} ], identification: [ { position: 100, label: 'Local currency', hidden: true}] }*/ @Semantics.currencyCode: true @Consumption.valueHelpDefinition: [ { entity: { name: 'I_Currency', element: 'Currency' } } ] loccurkey as LocalCurrency, @UI:{ identification: [ { position: 110, label: 'Customer Number'}] } customid, @UI:{ identification: [ { position: 120, label: 'Travel Agency Number'}] } agencynum, @UI: { lineItem: [ { position: 130, importance: #HIGH }, { type: #FOR_ACTION, dataAction: 'reservation', label: 'Reservation' } ] } reserved, //public associations _Currency }
**3.创建行为定义
**
unmanaged implementation in class zcl_bp_ibook unique;
define behavior for ZIBOOK alias booking//late numbering lock master// authorization master ( instance )//etag master <field_name>{ create; update; delete;
field (mandatory) carrid, connid, fldate, bookid;
//field (read only) ORDER_DATE;
// instance action and dynamic action control action ( features : instance ) reservation result [1] $self;
// validations //validation validateCustomer on save { field customid; }
//determination CalculateTravelKey on modify //{ create; }}
实施类中添加自定义的CURD逻辑和action逻辑, 注意代码添加在实施类的局部实施当中
CLASS lhc_booking DEFINITION INHERITING FROM cl_abap_behavior_handler.PUBLIC SECTION.
CLASS-DATA: mt_book TYPE STANDARD TABLE OF sbook WITH NON-UNIQUE DEFAULT KEY.PRIVATE SECTION.
TYPES: ty_action(2) TYPE c, tt_message TYPE TABLE OF symsg, tt_book_failed TYPE TABLE FOR FAILED zibook, tt_book_reported TYPE TABLE FOR REPORTED zibook.
CONSTANTS: BEGIN OF cs_action, create TYPE ty_action VALUE '01', update TYPE ty_action VALUE '02', delete TYPE ty_action VALUE '03', END OF cs_action.METHODS create FOR MODIFY IMPORTING entities FOR CREATE booking.
METHODS delete FOR MODIFY IMPORTING keys FOR DELETE booking.
METHODS update FOR MODIFY IMPORTING entities FOR UPDATE booking.
METHODS lock FOR BEHAVIOR IMPORTING keys FOR LOCK booking.
METHODS read FOR BEHAVIOR IMPORTING keys FOR READ booking RESULT result.
METHODS validate IMPORTING iv_action TYPE ty_action is_book TYPE sbook RETURNING VALUE(rv_message) TYPE string.METHODS set_reserved FOR MODIFY IMPORTING keys FOR ACTION booking~reservation RESULT result.
METHODS get_features FOR FEATURES IMPORTING keys REQUEST requested_features FOR booking RESULT result.
ENDCLASS.
CLASS lhc_booking IMPLEMENTATION.
METHOD create.
DATA: lt_sbook TYPE TABLE OF sbook, ls_sbook TYPE sbook.
LOOP AT entities INTO DATA(ls_entity).
DATA(lv_message) = validate( iv_action = cs_action-create is_book = CORRESPONDING sbook( ls_entity ) ).
IF lv_message IS INITIAL. "ls_root_to_create-order_user = syst-uname. "GET TIME STAMP FIELD ls_root_to_create-order_date.
ls_sbook = CORRESPONDING #( ls_entity ). ls_sbook-order_date = sy-datum. INSERT ls_sbook INTO TABLE mt_book.
INSERT CORRESPONDING #( ls_sbook ) INTO TABLE mapped-booking. ELSE. APPEND VALUE #( %cid = ls_entity-%cid carrid = ls_entity-carrid connid = ls_entity-connid fldate = ls...