Notice
Recent Posts
Recent Comments
Link
ExpertsUI5
Walkthrough 본문
https://openui5.hana.ondemand.com/#/topic/3da5f4be63264db99f2e5b04c5e853db
2019-01-08
Step 1: Hello World!
webapp 폴더 생성 후 webapp 폴더에 index.html 파일 생성
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>SAPUI5 Walkthrough</title> </head> <body> <div>Hello World</div> </body> </html> | cs |
Step 2: Bootstrap
스크립트... 뭔지 잘 모르겠다...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>SAPUI5 Walkthrough</title> <script id ="sap-ui-bootstrap" src ="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" data-sap-ui-theme ="sap_belize" data-sap-ui-libs ="sap.m" data-sap-ui-compatVersion ="edge" data-sap-ui-async ="true" data-sap-ui-onInit ="module:sap/ui/demo/walkthrough/index" data-sap-ui-resourceroots ='{ "sap.ui.demo.walkthrough": "./" }'> </script> </head> <body> <div>Hello World</div> </body> </html> | cs |
index.js 파일 생성
/* eslint-disable no-alert 주석이 있어야함 */
1 2 3 4 5 6 7 8 | sap.ui.define([ ], function () { "use strict"; /* eslint-disable no-alert */ alert("UI5 is ready"); }); | cs |
Step 3: Controls
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>SAPUI5 Walkthrough</title> <script id ="sap-ui-bootstrap" src ="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" data-sap-ui-theme ="sap_belize" data-sap-ui-libs ="sap.m" data-sap-ui-compatVersion ="edge" data-sap-ui-async ="true" data-sap-ui-onInit ="module:sap/ui/demo/walkthrough/index" data-sap-ui-resourceroots ='{ "sap.ui.demo.walkthrough": "./" }'> </script> </head> <body class="sapUiBody" id="content"> </body> </html> | cs |
1 2 3 4 5 6 7 8 9 10 11 | sap.ui.define([ "sap/m/Text" ], function (Text) { "use strict"; new Text({ text: "Hello World" }).placeAt("content"); }); | cs |
https://sapui5.hana.ondemand.com/#/api/sap.m.Text
https://sapui5.hana.ondemand.com/#/api/sap.ui.core.Control/methods/placeAt
Step 4: XML views
webapp 폴더 하위에 view 폴더 생성 후 App.view.xml 파일 생성
sap.m 네임스페이스
Model-View-Controller (MVC)
1 2 3 4 5 | <mvc:View xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc"> <Text text="Hello World"/> </mvc:View> | cs |
https://sapui5.hana.ondemand.com/#/api/sap.ui.core.mvc
1 2 3 4 5 6 7 8 9 10 11 12 | sap.ui.define([ "sap/ui/core/mvc/XMLView" ], function (XMLView) { "use strict"; XMLView.create({ viewName: "sap.ui.demo.walkthrough.view.App" }).then(function (oView) { oView.placeAt("content"); }); }); | cs |
https://sapui5.hana.ondemand.com/#/api/sap.ui.core.mvc.XMLView
Step 5: Controllers
1 2 3 4 5 6 7 8 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.App" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc"> <Button text="Say Hello" press=".onShowHello"/> </mvc:View> | cs |
webapp 폴더 하위에 controller 폴더 생성 후 App.controller.js 파일 생성
1 2 3 4 5 6 7 | sap.ui.define([ "sap/ui/core/mvc/Controller" ], function (Controller) { "use strict"; return Controller.extend("", { }); }); | cs |
https://sapui5.hana.ondemand.com/#/api/sap.ui.core.mvc.Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | sap.ui.define([ "sap/ui/core/mvc/Controller" ], function (Controller) { "use strict"; return Controller.extend("sap.ui.demo.walkthrough.controller.App", { onShowHello : function () { // show a native JavaScript alert /* eslint-disable no-alert */ alert("Hello World"); /* eslint-enable no-alert */ } }); }); | cs |
2019-01-09
Step 6: Modules
1 2 3 4 5 6 7 8 9 10 11 | sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/m/MessageToast" ], function (Controller, MessageToast) { "use strict"; return Controller.extend("sap.ui.demo.walkthrough.controller.App", { onShowHello : function () { MessageToast.show("Hello World"); } }); }); | cs |
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 | sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/m/MessageToast" ], function (Controller, MessageToast) { "use strict"; return Controller.extend("sap.ui.demo.walkthrough.controller.App", { onShowHello : function () { MessageToast.show("Hello World", { duration: 3000, // 지속시간 3초 width: "15em", // 가로 15em my: "center bottom", // default at: "center bottom", // default of: window, // default offset: "0 0", // default collision: "fit fit", // default onClose: null, // default autoClose: true, // default animationTimingFunction: "ease", // default animationDuration: 1000, // default closeOnBrowserNavigation: true // default }); } }); }); | cs |
https://sapui5.hana.ondemand.com/#/api/sap.m.MessageToast
Step 7: JSON Model
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 | sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/m/MessageToast", "sap/ui/model/json/JSONModel" ], function (Controller, MessageToast, JSONModel) { "use strict"; return Controller.extend("sap.ui.demo.walkthrough.controller.App", { onInit : function () { // set data model on view var oData = { recipient : { name : "World" } }; var oModel = new JSONModel(oData); this.getView().setModel(oModel); }, onShowHello : function () { MessageToast.show("Hello World"); } }); }); | cs |
https://sapui5.hana.ondemand.com/#/api/sap.ui.model.json.JSONModel
1 2 3 4 5 6 7 8 9 10 11 12 13 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.App" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc"> <Button text="Say Hello" press=".onShowHello"/> <Input value="{/recipient/name}" description="Hello {/recipient/name}" valueLiveUpdate="true" width="60%"/> </mvc:View> | cs |
Step 8: Translatable Texts
webapp 폴더 하위에 i18n 폴더 생성 후 i18n.properties 파일 생성
1 2 | showHelloButtonText=Say Hello helloMsg=Hello {0} | cs |
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 | sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/m/MessageToast", "sap/ui/model/json/JSONModel", "sap/ui/model/resource/ResourceModel" ], function (Controller, MessageToast, JSONModel, ResourceModel) { "use strict"; return Controller.extend("sap.ui.demo.walkthrough.controller.App", { onInit : function () { // set data model on view var oData = { recipient : { name : "World" } }; var oModel = new JSONModel(oData); this.getView().setModel(oModel); // set i18n model on view var i18nModel = new ResourceModel({ bundleName: "sap.ui.demo.walkthrough.i18n.i18n" }); this.getView().setModel(i18nModel, "i18n"); }, onShowHello : function () { // read msg from i18n model var oBundle = this.getView().getModel("i18n").getResourceBundle(); var sRecipient = this.getView().getModel().getProperty("/recipient/name"); var sMsg = oBundle.getText("helloMsg", [sRecipient]); // show message MessageToast.show(sMsg); } }); }); | cs |
https://sapui5.hana.ondemand.com/#/api/sap.ui.model.resource.ResourceModel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.App" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc"> <Button text="{i18n>showHelloButtonText}" press=".onShowHello"/> <Input value="{/recipient/name}" description="Hello {/recipient/name}" valueLiveUpdate="true" width="60%"/> </mvc:View> | cs |
Step 9: Component Configuration
webapp 폴더 하위에 Component.js 파일 생성
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 | sap.ui.define([ "sap/ui/core/UIComponent", "sap/ui/model/json/JSONModel", "sap/ui/model/resource/ResourceModel" ], function (UIComponent, JSONModel, ResourceModel) { "use strict"; return UIComponent.extend("sap.ui.demo.walkthrough.Component", { metadata : { "rootView": { "viewName": "sap.ui.demo.walkthrough.view.App", "type": "XML", "async": true, "id": "app" } }, init : function () { // call the init function of the parent UIComponent.prototype.init.apply(this, arguments); // set data model var oData = { recipient : { name : "World" } }; var oModel = new JSONModel(oData); this.setModel(oModel); // set i18n model var i18nModel = new ResourceModel({ bundleName : "sap.ui.demo.walkthrough.i18n.i18n" }); this.setModel(i18nModel, "i18n"); } }); }); | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/m/MessageToast" ], function (Controller, MessageToast) { "use strict"; return Controller.extend("sap.ui.demo.walkthrough.controller.App", { onShowHello : function () { // read msg from i18n model var oBundle = this.getView().getModel("i18n").getResourceBundle(); var sRecipient = this.getView().getModel().getProperty("/recipient/name"); var sMsg = oBundle.getText("helloMsg", [sRecipient]); // show message MessageToast.show(sMsg); } }); }); | cs |
index.js 파일 삭제
index.html 수정
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 | <!DOCTYPE html> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta charset="utf-8"> <title>SAPUI5 Walkthrough</title> <script id="sap-ui-bootstrap" src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" data-sap-ui-theme="sap_belize" data-sap-ui-libs="sap.m" data-sap-ui-compatVersion="edge" data-sap-ui-preload="async" data-sap-ui-resourceroots='{ "sap.ui.demo.walkthrough": "./" }'> </script> <script> sap.ui.getCore().attachInit(function () { sap.ui.require([ "sap/ui/core/ComponentContainer" ], function (ComponentContainer) { new ComponentContainer({ name: "sap.ui.demo.walkthrough", settings : { id : "walkthrough" } }).placeAt("content"); }); }); </script> </head> <body class="sapUiBody" id="content"> </body> </html> | cs |
2019-01-18
Step 10: Descriptor for Applications
webapp 폴더 하위에 manifest.json 파일 생성
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 | { "_version": "1.12.0", "sap.app": { "id": "sap.ui.demo.walkthrough", "type": "application", "i18n": "i18n/i18n.properties", "title": "{{appTitle}}", "description": "{{appDescription}}", "applicationVersion": { "version": "1.0.0" } }, "sap.ui": { "technology": "UI5", "deviceTypes": { "desktop": true, "tablet": true, "phone": true } }, "sap.ui5": { "rootView": { "viewName": "sap.ui.demo.walkthrough.view.App", "type": "XML", "async": true, "id": "app" }, "dependencies": { "minUI5Version": "1.60", "libs": { "sap.m": {} } }, "models": { "i18n": { "type": "sap.ui.model.resource.ResourceModel", "settings": { "bundleName": "sap.ui.demo.walkthrough.i18n.i18n" } } } } } | cs |
i18n.properties 파일 수정
1 2 3 4 5 6 7 8 | # App Descriptor appTitle=Hello World appDescription=A simple walkthrough app that explains the most important concepts of SAPUI5 # Hello Panel showHelloButtonText=Say Hello helloMsg=Hello {0} | cs |
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 | sap.ui.define([ "sap/ui/core/UIComponent", "sap/ui/model/json/JSONModel", ], function (UIComponent, JSONModel) { "use strict"; return UIComponent.extend("sap.ui.demo.walkthrough.Component", { metadata : { manifest : "json" }, init : function () { // call the init function of the parent UIComponent.prototype.init.apply(this, arguments); // set data model var oData = { recipient : { name : "World" } }; var oModel = new JSONModel(oData); this.setModel(oModel); } }); }); | cs |
Step 11: Pages and Panels
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 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.App" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" displayBlock="true"> <App> <pages> <Page title="{i18n>homePageTitle}"> <content> <Panel headerText="{i18n>helloPanelTitle}"> <content> <Button text="{i18n>showHelloButtonText}" press=".onShowHello"/> <Input value="{/recipient/name}" description="Hello {/recipient/name}" valueLiveUpdate="true" width="60%"/> </content> </Panel> </content> </Page> </pages> </App> </mvc:View> | cs |
1 2 3 4 5 6 7 8 9 | # App Descriptor appTitle=SAPUI5 Walkthrough appDescription=A simple walkthrough app that explains the most important concepts of SAPUI5 # Hello Panel showHelloButtonText=Say Hello helloMsg=Hello {0} homePageTitle=SAPUI5 Walkthrough helloPanelTitle=Hello World | cs |
Step 12: Shell Control as Container
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 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.App" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" displayBlock="true"> <Shell> <App> <pages> <Page title="{i18n>homePageTitle}"> <content> <Panel headerText="{i18n>helloPanelTitle}"> <content> <Button text="{i18n>showHelloButtonText}" press=".onShowHello"/> <Input value="{/recipient/name}" description="Hello {/recipient/name}" valueLiveUpdate="true" width="60%"/> </content> </Panel> </content> </Page> </pages> </App> </Shell> </mvc:View> | cs |
Step 13: Margins and Paddings
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 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.App" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" displayBlock="true"> <Shell> <App> <pages> <Page title="{i18n>homePageTitle}"> <content> <Panel headerText="{i18n>helloPanelTitle}" class="sapUiResponsiveMargin" width="auto"> <content> <Button text="{i18n>showHelloButtonText}" press=".onShowHello" class="sapUiSmallMarginEnd"/> <Input value="{/recipient/name}" valueLiveUpdate="true" width="60%"/> <Text text="Hello {/recipient/name}" class="sapUiSmallMargin"/> </content> </Panel> </content> </Page> </pages> </App> </Shell> </mvc:View> | cs |
Step 14: Custom CSS and Theme Colors
webapp 폴더 하위에 css 폴더 생성 후 style.css 파일 생성
1 2 3 4 5 6 7 8 9 10 11 12 | html[dir="ltr"] .myAppDemoWT .myCustomButton.sapMBtn { margin-right: 0.125rem } html[dir="rtl"] .myAppDemoWT .myCustomButton.sapMBtn { margin-left: 0.125rem } .myAppDemoWT .myCustomText { display: inline-block; font-weight: bold; } | cs |
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 | { "_version": "1.12.0", "sap.app": { "id": "sap.ui.demo.walkthrough", "type": "application", "i18n": "i18n/i18n.properties", "title": "{{appTitle}}", "description": "{{appDescription}}", "applicationVersion": { "version": "1.0.0" } }, "sap.ui": { "technology": "UI5", "deviceTypes": { "desktop": true, "tablet": true, "phone": true } }, "sap.ui5": { "rootView": { "viewName": "sap.ui.demo.walkthrough.view.App", "type": "XML", "async": true, "id": "app" }, "dependencies": { "minUI5Version": "1.60", "libs": { "sap.m": {} } }, "config": { "invoiceLocal": "/Invoices.json" }, "models": { "i18n": { "type": "sap.ui.model.resource.ResourceModel", "settings": { "bundleName": "sap.ui.demo.walkthrough.i18n.i18n" } } }, "resources": { "css": [ { "uri": "css/style.css" } ] } } } | cs |
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 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.App" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" displayBlock="true"> <Shell> <App class="myAppDemoWT"> <pages> <Page title="{i18n>homePageTitle}"> <content> <Panel headerText="{i18n>helloPanelTitle}" class="sapUiResponsiveMargin" width="auto"> <content> <Button text="{i18n>showHelloButtonText}" press=".onShowHello" class="myCustomButton"/> <Input value="{/recipient/name}" valueLiveUpdate="true" width="60%"/> <FormattedText htmlText="Hello {/recipient/name}" class="sapUiSmallMargin sapThemeHighlight-asColor myCustomText"/> </content> </Panel> </content> </Page> </pages> </App> </Shell> </mvc:View> | cs |
Step 15: Nested Views
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.App" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" displayBlock="true"> <Shell> <App class="myAppDemoWT"> <pages> <Page title="{i18n>homePageTitle}"> <content> <mvc:XMLView viewName="sap.ui.demo.walkthrough.view.HelloPanel"/> </content> </Page> </pages> </App> </Shell> </mvc:View> | cs |
view 폴더 하위에 HelloPanel.view.xml 파일 생성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.HelloPanel" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc"> <Panel headerText="{i18n>helloPanelTitle}" class="sapUiResponsiveMargin" width="auto"> <content> <Button text="{i18n>showHelloButtonText}" press=".onShowHello" class="myCustomButton"/> <Input value="{/recipient/name}" valueLiveUpdate="true" width="60%"/> <FormattedText htmlText="Hello {/recipient/name}" class="sapUiSmallMargin sapThemeHighlight-asColor myCustomText"/> </content> </Panel> </mvc:View> | cs |
controller 폴더 하위에 HelloPanel.controller.js 파일 생성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/m/MessageToast" ], function (Controller, MessageToast) { "use strict"; return Controller.extend("sap.ui.demo.walkthrough.controller.HelloPanel", { onShowHello : function () { // read msg from i18n model var oBundle = this.getView().getModel("i18n").getResourceBundle(); var sRecipient = this.getView().getModel().getProperty("/recipient/name"); var sMsg = oBundle.getText("helloMsg", [sRecipient]); // show message MessageToast.show(sMsg); } }); }); | cs |
1 2 3 4 5 6 7 8 9 | sap.ui.define([ "sap/ui/core/mvc/Controller" ], function (Controller) { "use strict"; return Controller.extend("sap.ui.demo.walkthrough.controller.App", { }); }); | cs |
Step 16: Dialogs and Fragments
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 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.HelloPanel" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc"> <Panel headerText="{i18n>helloPanelTitle}" class="sapUiResponsiveMargin" width="auto"> <content> <Button id="helloDialogButton" text="{i18n>openDialogButtonText}" press=".onOpenDialog" class="sapUiSmallMarginEnd"/> <Button text="{i18n>showHelloButtonText}" press=".onShowHello" class="myCustomButton"/> <Input value="{/recipient/name}" valueLiveUpdate="true" width="60%"/> <FormattedText htmlText="Hello {/recipient/name}" class="sapUiSmallMargin sapThemeHighlight-asColor myCustomText"/> </content> </Panel> </mvc:View> | cs |
view 폴더 하위에 HelloDialog.fragment.xml 파일 생성
1 2 3 4 5 6 7 8 9 | <core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core"> <Dialog id="helloDialog" title="Hello {/recipient/name}"> </Dialog> </core:FragmentDefinition> | cs |
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 | sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/m/MessageToast", "sap/ui/core/Fragment" ], function (Controller, MessageToast, Fragment) { "use strict"; return Controller.extend("sap.ui.demo.walkthrough.controller.HelloPanel", { onShowHello : function () { // read msg from i18n model var oBundle = this.getView().getModel("i18n").getResourceBundle(); var sRecipient = this.getView().getModel().getProperty("/recipient/name"); var sMsg = oBundle.getText("helloMsg", [sRecipient]); // show message MessageToast.show(sMsg); }, onOpenDialog : function () { var oView = this.getView(); // create dialog lazily if (!this.byId("helloDialog")) { // load asynchronous XML fragment Fragment.load({ id: oView.getId(), name: "sap.ui.demo.walkthrough.view.HelloDialog" }).then(function (oDialog) { // connect dialog to the root view of this component (models, lifecycle) oView.addDependent(oDialog); oDialog.open(); }); } else { this.byId("helloDialog").open(); } } }); }); | cs |
Step 17: Fragment Callbacks
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 | sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/m/MessageToast", "sap/ui/core/Fragment" ], function (Controller, MessageToast, Fragment) { "use strict"; return Controller.extend("sap.ui.demo.walkthrough.controller.HelloPanel", { onShowHello : function () { // read msg from i18n model var oBundle = this.getView().getModel("i18n").getResourceBundle(); var sRecipient = this.getView().getModel().getProperty("/recipient/name"); var sMsg = oBundle.getText("helloMsg", [sRecipient]); // show message MessageToast.show(sMsg); }, onOpenDialog : function () { var oView = this.getView(); // create dialog lazily if (!this.byId("helloDialog")) { // load asynchronous XML fragment Fragment.load({ id: oView.getId(), name: "sap.ui.demo.walkthrough.view.HelloDialog", controller: this }).then(function (oDialog) { // connect dialog to the root view of this component (models, lifecycle) oView.addDependent(oDialog); oDialog.open(); }); } else { this.byId("helloDialog").open(); } }, onCloseDialog : function () { this.byId("helloDialog").close(); } }); }); | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core"> <Dialog id="helloDialog" title="Hello {/recipient/name}"> <beginButton> <Button text="{i18n>dialogCloseButtonText}" press=".onCloseDialog"/> </beginButton> </Dialog> </core:FragmentDefinition> | cs |
1 2 3 4 5 6 7 8 9 10 11 12 | # App Descriptor appTitle=SAPUI5 Walkthrough appDescription=A simple walkthrough app that explains the most important concepts of SAPUI5 # Hello Panel showHelloButtonText=Say Hello helloMsg=Hello {0} homePageTitle=SAPUI5 Walkthrough helloPanelTitle=Hello World openDialogButtonText=Say Hello With Dialog dialogCloseButtonText=Ok | cs |
Step 18: Icons
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 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.HelloPanel" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc"> <Panel headerText="{i18n>helloPanelTitle}" class="sapUiResponsiveMargin" width="auto"> <content> <Button id="helloDialogButton" icon="sap-icon://world" text="{i18n>openDialogButtonText}" press=".onOpenDialog" class="sapUiSmallMarginEnd"/> <Button text="{i18n>showHelloButtonText}" press=".onShowHello" class="myCustomButton"/> <Input value="{/recipient/name}" valueLiveUpdate="true" width="60%"/> <FormattedText htmlText="Hello {/recipient/name}" class="sapUiSmallMargin sapThemeHighlight-asColor myCustomText"/> </content> </Panel> </mvc:View> | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core"> <Dialog id="helloDialog" title="Hello {/recipient/name}"> <content> <core:Icon src="sap-icon://hello-world" size="8rem" class="sapUiMediumMargin"/> </content> <beginButton> <Button text="{i18n>dialogCloseButtonText}" press=".onCloseDialog"/> </beginButton> </Dialog> </core:FragmentDefinition> | cs |
Step 19: Reuse Dialogs
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 | sap.ui.define([ "sap/ui/core/UIComponent", "sap/ui/model/json/JSONModel", "./controller/HelloDialog" ], function (UIComponent, JSONModel, HelloDialog) { "use strict"; return UIComponent.extend("sap.ui.demo.walkthrough.Component", { metadata : { manifest: "json" }, init : function () { // call the init function of the parent UIComponent.prototype.init.apply(this, arguments); // set data model var oData = { recipient : { name : "World" } }; var oModel = new JSONModel(oData); this.setModel(oModel); // set dialog this._helloDialog = new HelloDialog(this.getRootControl()); }, exit : function () { this._helloDialog.destroy(); delete this._helloDialog; }, openHelloDialog : function () { this._helloDialog.open(); } }); }); | cs |
controller 폴더 하위에 HelloDialog.js 파일 생성
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 | sap.ui.define([ "sap/ui/base/ManagedObject", "sap/ui/core/Fragment" ], function (ManagedObject, Fragment) { "use strict"; return ManagedObject.extend("sap.ui.demo.walkthrough.controller.HelloDialog", { constructor : function (oView) { this._oView = oView; }, exit : function () { delete this._oView; }, open : function () { var oView = this._oView; // create dialog lazily if (!oView.byId("helloDialog")) { var oFragmentController = { onCloseDialog : function () { oView.byId("helloDialog").close(); } }; // load asynchronous XML fragment Fragment.load({ id: oView.getId(), name: "sap.ui.demo.walkthrough.view.HelloDialog", controller: oFragmentController }).then(function (oDialog) { // connect dialog to the root view of this component (models, lifecycle) oView.addDependent(oDialog); oDialog.open(); }); } else { oView.byId("helloDialog").open(); } } }); }); | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/m/MessageToast" ], function (Controller, MessageToast) { "use strict"; return Controller.extend("sap.ui.demo.walkthrough.controller.HelloPanel", { onShowHello : function () { // read msg from i18n model var oBundle = this.getView().getModel("i18n").getResourceBundle(); var sRecipient = this.getView().getModel().getProperty("/recipient/name"); var sMsg = oBundle.getText("helloMsg", [sRecipient]); // show message MessageToast.show(sMsg); }, onOpenDialog : function () { this.getOwnerComponent().openHelloDialog(); } }); }); | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.App" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" displayBlock="true"> <Shell> <App class="myAppDemoWT"> <pages> <Page title="{i18n>homePageTitle}"> <headerContent> <Button icon="sap-icon://hello-world" press=".onOpenDialog"/> </headerContent> <content> <mvc:XMLView viewName="sap.ui.demo.walkthrough.view.HelloPanel"/> </content> </Page> </pages> </App> </Shell> </mvc:View> | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 | sap.ui.define([ "sap/ui/core/mvc/Controller" ], function (Controller) { "use strict"; return Controller.extend("sap.ui.demo.walkthrough.controller.App", { onOpenDialog : function () { this.getOwnerComponent().openHelloDialog(); } }); }); | cs |
Step 20: Aggregation Binding
webapp 폴더 하위에 Invoices.json 파일 생성
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 | { "Invoices": [ { "ProductName": "Pineapple", "Quantity": 21, "ExtendedPrice": 87.2000, "ShipperName": "Fun Inc.", "ShippedDate": "2015-04-01T00:00:00", "Status": "A" }, { "ProductName": "Milk", "Quantity": 4, "ExtendedPrice": 9.99999, "ShipperName": "ACME", "ShippedDate": "2015-02-18T00:00:00", "Status": "B" }, { "ProductName": "Canned Beans", "Quantity": 3, "ExtendedPrice": 6.85000, "ShipperName": "ACME", "ShippedDate": "2015-03-02T00:00:00", "Status": "B" }, { "ProductName": "Salad", "Quantity": 2, "ExtendedPrice": 8.8000, "ShipperName": "ACME", "ShippedDate": "2015-04-12T00:00:00", "Status": "C" }, { "ProductName": "Bread", "Quantity": 1, "ExtendedPrice": 2.71212, "ShipperName": "Fun Inc.", "ShippedDate": "2015-01-27T00:00:00", "Status": "A" } ] } | cs |
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 | { "_version": "1.12.0", "sap.app": { "id": "sap.ui.demo.walkthrough", "type": "application", "i18n": "i18n/i18n.properties", "title": "{{appTitle}}", "description": "{{appDescription}}", "applicationVersion": { "version": "1.0.0" } }, "sap.ui": { "technology": "UI5", "deviceTypes": { "desktop": true, "tablet": true, "phone": true } }, "sap.ui5": { "rootView": { "viewName": "sap.ui.demo.walkthrough.view.App", "type": "XML", "async": true, "id": "app" }, "dependencies": { "minUI5Version": "1.60", "libs": { "sap.m": {} } }, "models": { "i18n": { "type": "sap.ui.model.resource.ResourceModel", "settings": { "bundleName": "sap.ui.demo.walkthrough.i18n.i18n" } }, "invoice": { "type": "sap.ui.model.json.JSONModel", "uri": "Invoices.json" } }, "resources": { "css": [ { "uri": "css/style.css" } ] } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.App" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" displayBlock="true"> <Shell> <App class="myAppDemoWT"> <pages> <Page title="{i18n>homePageTitle}"> <headerContent> <Button icon="sap-icon://hello-world" press=".onOpenDialog"/> </headerContent> <content> <mvc:XMLView viewName="sap.ui.demo.walkthrough.view.HelloPanel"/> <mvc:XMLView viewName="sap.ui.demo.walkthrough.view.InvoiceList"/> </content> </Page> </pages> </App> </Shell> </mvc:View> | cs |
view 폴더 하위에 InvoiceList.view.xml 파일 생성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <mvc:View xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc"> <List headerText="{i18n>invoiceListTitle}" class="sapUiResponsiveMargin" width="auto" items="{invoice>/Invoices}"> <items> <ObjectListItem title="{invoice>Quantity} x {invoice>ProductName}"/> </items> </List> </mvc:View> | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # App Descriptor appTitle=SAPUI5 Walkthrough appDescription=A simple walkthrough app that explains the most important concepts of SAPUI5 # Hello Panel showHelloButtonText=Say Hello helloMsg=Hello {0} homePageTitle=SAPUI5 Walkthrough helloPanelTitle=Hello World openDialogButtonText=Say Hello With Dialog dialogCloseButtonText=Ok # Invoice List invoiceListTitle=Invoices | cs |
Step 21: Data Types
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.InvoiceList" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc"> <List headerText="{i18n>invoiceListTitle}" class="sapUiResponsiveMargin" width="auto" items="{invoice>/Invoices}"> <items> <ObjectListItem title="{invoice>Quantity} x {invoice>ProductName}" number="{ parts: [{path: 'invoice>ExtendedPrice'}, {path: 'view>/currency'}], type: 'sap.ui.model.type.Currency', formatOptions: { showMeasure: false } }" numberUnit="{view>/currency}"/> </items> </List> </mvc:View> | cs |
controller 폴더 하위에 InvoiceList.controller.js 파일 생성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/ui/model/json/JSONModel" ], function (Controller, JSONModel) { "use strict"; return Controller.extend("sap.ui.demo.walkthrough.controller.InvoiceList", { onInit: function () { var oViewModel = new JSONModel({ currency: "EUR" }); this.getView().setModel(oViewModel, "view"); } }); }); | cs |
Step 22: Expression Binding
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 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.InvoiceList" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc"> <List headerText="{i18n>invoiceListTitle}" class="sapUiResponsiveMargin" width="auto" items="{invoice>/Invoices}"> <items> <ObjectListItem title="{invoice>Quantity} x {invoice>ProductName}" number="{ parts: [{path: 'invoice>ExtendedPrice'}, {path: 'view>/currency'}], type: 'sap.ui.model.type.Currency', formatOptions: { showMeasure: false } }" numberUnit="{view>/currency}" numberState="{= ${invoice>ExtendedPrice} > 50 ? 'Error' : 'Success' }"/> </items> </List> </mvc:View> | cs |
Step 23: Custom Formatters
webapp 폴더 하위에 model 폴더 생성 후 formatter.js 파일 생성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | sap.ui.define([], function () { "use strict"; return { statusText: function (sStatus) { var oResourceBundle = this.getView().getModel("i18n").getResourceBundle(); switch (sStatus) { case "A": return oResourceBundle.getText("invoiceStatusA"); case "B": return oResourceBundle.getText("invoiceStatusB"); case "C": return oResourceBundle.getText("invoiceStatusC"); default: return sStatus; } } }; }); | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/ui/model/json/JSONModel", "../model/formatter" ], function (Controller, JSONModel, formatter) { "use strict"; return Controller.extend("sap.ui.demo.walkthrough.controller.InvoiceList", { formatter: formatter, onInit: function () { var oViewModel = new JSONModel({ currency: "EUR" }); this.getView().setModel(oViewModel, "view"); } }); }); | cs |
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 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.InvoiceList" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc"> <List headerText="{i18n>invoiceListTitle}" class="sapUiResponsiveMargin" width="auto" items="{invoice>/Invoices}"> <items> <ObjectListItem title="{invoice>Quantity} x {invoice>ProductName}" number="{ parts: [{path: 'invoice>ExtendedPrice'}, {path: 'view>/currency'}], type: 'sap.ui.model.type.Currency', formatOptions: { showMeasure: false } }" numberUnit="{view>/currency}" numberState="{= ${invoice>ExtendedPrice} > 50 ? 'Error' : 'Success' }"> <firstStatus> <ObjectStatus text="{ path: 'invoice>Status', formatter: '.formatter.statusText' }"/> </firstStatus> </ObjectListItem> </items> </List> </mvc:View> | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # App Descriptor appTitle=SAPUI5 Walkthrough appDescription=A simple walkthrough app that explains the most important concepts of SAPUI5 # Hello Panel showHelloButtonText=Say Hello helloMsg=Hello {0} homePageTitle=SAPUI5 Walkthrough helloPanelTitle=Hello World openDialogButtonText=Say Hello With Dialog dialogCloseButtonText=Ok # Invoice List invoiceListTitle=Invoices invoiceStatusA=New invoiceStatusB=In Progress invoiceStatusC=Done | cs |
Step 24: Filtering
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 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.InvoiceList" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc"> <List id="invoiceList" class="sapUiResponsiveMargin" width="auto" items="{invoice>/Invoices}"> <headerToolbar> <Toolbar> <Title text="{i18n>invoiceListTitle}"/> <ToolbarSpacer/> <SearchField width="50%" search="onFilterInvoices"/> </Toolbar> </headerToolbar> <items> <ObjectListItem title="{invoice>Quantity} x {invoice>ProductName}" number="{ parts: [{path: 'invoice>ExtendedPrice'}, {path: 'view>/currency'}], type: 'sap.ui.model.type.Currency', formatOptions: { showMeasure: false } }" numberUnit="{view>/currency}" numberState="{= ${invoice>ExtendedPrice} > 50 ? 'Error' : 'Success' }"> <firstStatus> <ObjectStatus text="{ path: 'invoice>Status', formatter: '.formatter.statusText' }"/> </firstStatus> </ObjectListItem> </items> </List> </mvc:View> | cs |
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 | sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/ui/model/json/JSONModel", "../model/formatter", "sap/ui/model/Filter", "sap/ui/model/FilterOperator" ], function (Controller, JSONModel, formatter, Filter, FilterOperator) { "use strict"; return Controller.extend("sap.ui.demo.walkthrough.controller.InvoiceList", { formatter: formatter, onInit: function () { var oViewModel = new JSONModel({ currency: "EUR" }); this.getView().setModel(oViewModel, "view"); }, onFilterInvoices : function (oEvent) { // build filter array var aFilter = []; var sQuery = oEvent.getParameter("query"); if (sQuery) { aFilter.push(new Filter("ProductName", FilterOperator.Contains, sQuery)); } // filter binding var oList = this.byId("invoiceList"); var oBinding = oList.getBinding("items"); oBinding.filter(aFilter); } }); }); | cs |
Step 25: Sorting and Grouping
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 | <mvc:View controllerName="sap.ui.demo.walkthrough.controller.InvoiceList" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc"> <List id="invoiceList" class="sapUiResponsiveMargin" width="auto" items="{ path : 'invoice>/Invoices', sorter : { path : 'ShipperName', group : true } }"> <headerToolbar> <Toolbar> <Title text="{i18n>invoiceListTitle}"/> <ToolbarSpacer/> <SearchField width="50%" search="onFilterInvoices"/> </Toolbar> </headerToolbar> <items> <ObjectListItem title="{invoice>Quantity} x {invoice>ProductName}" number="{ parts: [{path: 'invoice>ExtendedPrice'}, {path: 'view>/currency'}], type: 'sap.ui.model.type.Currency', formatOptions: { showMeasure: false } }" numberUnit="{view>/currency}" numberState="{= ${invoice>ExtendedPrice} > 50 ? 'Error' : 'Success' }"> <firstStatus> <ObjectStatus text="{ path: 'invoice>Status', formatter: '.formatter.statusText' }"/> </firstStatus> </ObjectListItem> </items> </List> </mvc:View> | cs |
Step 26: (Optional) Remote OData Service
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 | { "_version": "1.12.0", "sap.app": { "id": "sap.ui.demo.walkthrough", "type": "application", "i18n": "i18n/i18n.properties", "title": "{{appTitle}}", "description": "{{appDescription}}", "applicationVersion": { "version": "1.0.0" }, "dataSources": { "invoiceRemote": { "uri": "https://services.odata.org/V2/Northwind/Northwind.svc/", "type": "OData", "settings": { "odataVersion": "2.0" } } } }, "sap.ui": { "technology": "UI5", "deviceTypes": { "desktop": true, "tablet": true, "phone": true } }, "sap.ui5": { "rootView": { "viewName": "sap.ui.demo.walkthrough.view.App", "type": "XML", "async": true, "id": "app" }, "dependencies": { "minUI5Version": "1.60", "libs": { "sap.m": {} } }, "models": { "i18n": { "type": "sap.ui.model.resource.ResourceModel", "settings": { "bundleName": "sap.ui.demo.walkthrough.i18n.i18n" } }, "invoice": { "dataSource": "invoiceRemote" } }, "resources": { "css": [ { "uri": "css/style.css" } ] } } } | cs |
Step 27: Mock Server Configuration
Step 28: Unit Test with QUnit
Step 29: Integration Test with OPA
Step 30: Debugging Tools
Step 31: Routing and Navigation
Step 32: Routing with Parameters
Step 33: Routing Back and History
Step 34: Custom Controls
Step 35: Responsiveness
Step 36: Device Adaptation
Step 37: Content Density
Step 38: Accessibility
Comments