• 使用 SAP UI5 绘制 Business Rule Control


    本文我们介绍如何将 Business Rule Control 即规则控件,嵌入到 SAP UI5 应用程序视图中。

    RuleBuilder 组件是一个规则控件的容器,可以捆绑不同的可视化手段。 目前唯一可用的可视化是决策表(Decision Table)。 RuleBuilder 定义了 UI 开发者要遵循的通用规则 UI 消费模式和 API。

    在这个例子中,我们创建了一个决策表,它将使用引导输入模式。

    效果如下:

    可以切换条件:

    可以编辑 if 条件 和 then 结果:

    我们在 xml 视图里,使用的控件来自命名空间 sap.rules.ui 的标准控件:RuleBuilder,types 属性为 DecisionTable

    现在我们需要将 ExpressionLanguage 对象关联连接到 RuleBuilder,然后控件通过 OData 模型加载其数据。

    表达式语言(Expression languages)为规则创作、规则可视化和规则内容验证提供所需的服务。 表达式语言对象提供的服务包括表达式验证、表达式解析、自动完成建议、表达式元数据和令牌的检索,以及执行运行时服务,例如获取数据对象、输出等。

    特定词汇表的词汇表 OData 模型和绑定上下文路径是表达式语言的强制输入。

    表达式语言对象是 RuleBuilder 对象的关联,它可以关联多个 RuleBuilder 对象。

    我们可以根据项目实际要求:自定义 Page.controller.js。

    设置表达式语言对象:

    oExpressionLanguage = new sap.rules.ui.services.ExpressionLanguage();
    oRuleBuilder.setExpressionLanguage(oExpressionLanguage);
    
    • 1
    • 2

    如果使用 DMN SFEEL(Expression language 2.0),则代码如下:

    oAstExpressionLanguage = new sap.rules.ui.services.AstExpressionLanguage();
    oRuleBuilder.setAstExpressionLanguage(oAstExpressionLanguage);
    
    • 1
    • 2

    确保在设置表达式语言的词汇模型之前已设置数据,如图所示:

    oExpressionLanguage.setData(data);
    oExpressionLanguage.setModel(that.oVocabularyModel);
    
    • 1
    • 2

    控制器完整代码如下:

    sap.ui.define([
    	'jquery.sap.global',
    	'sap/ui/core/mvc/Controller',
    	'sap/ui/model/odata/v2/ODataModel',
    	'sap/rules/ui/services/ExpressionLanguage',   //For DMN SFEEL language, use 'AstExpressionLanguage'.
    	'sap/ui/core/util/MockServer',
    	'sap/m/MessageToast'
    ], function (jQuery, Controller, ODataModel, ExpressionLanguage, MockServer, MessageToast) {    //For DMN SFEEL language, use 'AstExpressionLanguage' instead of 'ExpressionLanguage'.
    	"use strict";
    
    	return Controller.extend("sap.rules.ui.sample.GuidedDecisionTable.Page", {
    
    		onInit: function () {
    
    			sap.ui.getCore().applyTheme("sap_belize");
    
    			// apply compact density for desktop, the cozy design otherwise
    			this.getView().addStyleClass(sap.ui.Device.system.desktop ? "sapUiSizeCompact" : "sapUiSizeCozy");
    
    			var mPath = sap.ui.require.toUrl("sap/rules/ui/sample/GuidedDecisionTable") + "/";
    			
    			// Initialize Expression Language services
    			this.oVocabularyMockServer = new MockServer({rootUri: "/sap/opu/odata/SAP/vocabulary_srv/"});
    			this.oVocabularyMockServer.simulate(
    				mPath + "localService/vocabulary/metadata.xml",
    				{'sMockdataBaseUrl': mPath + "localService/vocabulary/mockdata/"}
    			);
    			this.oVocabularyMockServer.start();
    			this.oVocabularyModel = new ODataModel("/sap/opu/odata/SAP/vocabulary_srv/");
    			this.oExpressionLanguage = new ExpressionLanguage();               //For DMN SFEEL, use 'new AstExpressionLanguage();'.
    			this.oExpressionLanguage.setModel(this.oVocabularyModel);
    			this.oExpressionLanguage.setBindingContextPath("/Vocabularies('FA163E38C6481EE785F409DCAD583D43')");
    
    			// Initialize the Rule Builder
    			this.oRuleMockServer = new MockServer({rootUri: "/sap/opu/odata/SAP/RULE_SRV/"});
    			this.oRuleMockServer.simulate(
    				mPath + "localService/rule/metadata.xml",
    				{'sMockdataBaseUrl': mPath + "localService/rule/mockdata/"}
    			);
    
    			var aRequests = this.loadRequests(mPath);
    			this.oRuleMockServer.setRequests(aRequests);
    			this.oRuleMockServer.start();
    			this.oRuleModel = new ODataModel({
    				serviceUrl: "/sap/opu/odata/SAP/RULE_SRV/",
    				defaultBindingMode: sap.ui.model.BindingMode.TwoWay
    			});
    
    			var oRuleBuilder = this.byId("ruleBuilder");
    			oRuleBuilder.setModel(this.oRuleModel);
    			oRuleBuilder.setExpressionLanguage(this.oExpressionLanguage);
    			oRuleBuilder.setBindingContextPath("/Rules(Id='FA163E38C6481EE785F409DCAD583D43',Version='000000000000000001')");
    		},
    
    		handleEditButton: function () {
    			var oEditButton = this.byId("editButton");
    			var oRuleBuilder = this.byId("ruleBuilder");
    			var bEdit = (oEditButton.getText() === "Edit");
    			oRuleBuilder.setEditable(bEdit);
    			oEditButton.setText(bEdit ? "Display" : "Edit");
    		},
    
    		onAfterRendering: function () {
    
    			// Line actions are not supported in this demo
    			var oRuleBuilder = this.byId("ruleBuilder");
    			var oDecisionTable = oRuleBuilder.getAggregation("_rule");
    			var oToolbar = oDecisionTable.getAggregation("_toolbar");
    			var arrContent = oToolbar.getContent();
    			for (var i = 0; i < arrContent.length; i++) {
    				if (arrContent[i].getMetadata().getName() === "sap.m.Button") {
    					arrContent[i].detachPress(arrContent[i].mEventRegistry.press[0].fFunction, arrContent[i].mEventRegistry.press[0].oListner);
    					arrContent[i].attachPress(function (oEvent) {
    							var msg = 'Line action pressed';
    							MessageToast.show(msg);
    						}
    					);
    				} else if (arrContent[i].getMetadata().getName() === "sap.m.MenuButton") {
    					var oMenu = arrContent[i].getMenu();
    					oMenu.detachItemSelected(oMenu.mEventRegistry.itemSelected[1].fFunction, oMenu.mEventRegistry.itemSelected[1].oListner);
    					oMenu.attachItemSelected(function (oEvent) {
    							var msg = 'Line action pressed';
    							MessageToast.show(msg);
    						}
    					);
    				}
    			}
    
    		},
    
    		loadRequests: function (mPath) {
    
    			// The mock server does not support 1 to 1 navigation.
    			// Hence we provide the responses directly by adding custom requests to the MockServer
    			var oRresponses = jQuery.sap.sjax({
    				type: "GET",
    				url: mPath + "localService/rule/responses.json",
    				dataType: "json"
    				}	
    			).data;
    			
    			var aRequests = this.oRuleMockServer.getRequests();
    			var sMethod = "GET";
    			var sPath = /Rules\(Id='FA163E38C6481EE785F409DCAD583D43',Version='000001'\)\/DecisionTable\/DecisionTableRows\/\$count/;
    			var fnResponse1 = function (xhr) {
    				xhr.respond(200, {
    					"Content-Type": "text/plain;charset=utf-8"
    				}, "5");
    			};
    			aRequests.push({method: sMethod, path: sPath, response: fnResponse1});
    			
    			sPath = /Rules\(Id='FA163E38C6481EE785F409DCAD583D43',Version='000001'\)\/DecisionTable\/DecisionTableRows\?\$skip=0&\$top=\d+&\$orderby=Sequence%20asc&\$expand=Cells/;
    			var response_1 = this.response_1;
    			var fnResponse2 = function (xhr) {
    				xhr.respondJSON(200, {
    					"Content-Type": "application/json;charset=utf-8"
    				}, oRresponses.response_1);
    			};
    			aRequests.push({method: sMethod, path: sPath, response: fnResponse2});
    
    			sPath = /Rules\(Id='FA163E38C6481EE785F409DCAD583D43',Version='000001'\)\/DecisionTable\/DecisionTableColumns\/\$count/;
    			var fnResponse3 = function (xhr) {
    				xhr.respond(200, {
    					"Content-Type": "text/plain;charset=utf-8"
    				}, "5");
    			}
    			aRequests.push({method: sMethod, path: sPath, response: fnResponse3});
    
    			sPath = /Rules\(Id='FA163E38C6481EE785F409DCAD583D43',Version='000001'\)\/DecisionTable\/DecisionTableColumns\?\$skip=0&\$top=\d+&\$expand=Condition%2cResult/;
    			var response_2 = this.response_2;
    			var fnResponse4 = function (xhr) {
    				xhr.respondJSON(200, {
    					"Content-Type": "application/json;charset=utf-8"
    				}, oRresponses.response_2);
    			}
    			aRequests.push({method: sMethod, path: sPath, response: fnResponse4});
     
    			return aRequests;
    		}
    	});
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
  • 相关阅读:
    Virtual Data Augmentation: 虚拟数据扩增技术
    大型电商系统的订单设计
    GFS分布式存储
    Photoshop-图层相关概念-LayerComp-Layers-移动旋转复制图层-复合图层
    微电影拍摄制作的基本流程有哪些?
    Nvidia Jetson/Orin +FPGA+AI大算力边缘计算盒子:公路智能巡检解决方案
    Nacos技术学习与总结待续
    温湿度监控系统——保障鲜花冷链运输
    Python数据分析----Numpy函数应用(二)
    就业班 第四阶段(k8s) 2401--6.3 day1 kubernetes 部署k8s集群[单master]+[配有haproxy的master]
  • 原文地址:https://blog.csdn.net/i042416/article/details/126687708