我曾经于2014年10月到2016年5月工作于SAP CRM Fiori应用的开发团队, 我所在的团队负责下列这8个Fiori应用的维护和持续开发:

  • My Opportunities
  • My Tasks
  • My Appointments
  • My Leads
  • My Notes
  • Simulate Sales Pipeline
  • Track Sales Pipeline

在这不到两年的开发工作里,我在使用SAP UI5的过程中遇到各种各样的问题,我都把它们一一记录了下来。还有一些问题来源于我的好奇心,比如看到了一些UI效果,想知道它背后是怎么实现的;又比如观察到了一些系统的看起来有点怪的行为,我想知道它究竟是确实就是这样设计的,还是说我观察到的其实是bug。另外一类问题是同样的应用,在系统A的行为是a,在系统B的行为是b。作为强迫症患者,我总是要通过调试的方式搞清楚原因。对于这种我自己给自己提的问题,弄清楚答案之后我也记录了下来,以备将来哪一天又会用到。


1. Explore the com.sap.ui5.resource.ResourceServlet

我们在本地做Fiori开发时,经常通过这样的方式引入UI5的库文件。我刚接触UI5时,就问过自己一个问题: 这个sap-ui-core.js在这里是通过相对路径引入的。当Fiori应用在本地的服务器比如Tomcat启动时,到底是从哪个位置加载的该文件?

https://blogs.sap.com/2014/12/04/explore-the-comsapui5resourceresourceservlet/

2. My small experience about how to find the exact line position which causes “undefined is not a function” error

Partner比较容易遇到的问题: 实施了Fiori,或者在标准Fiori应用上做了一些二次开发,打开应用时白屏,Chrome的开发工具里有一些报错信息,但是不知道该如何定义到具体哪一行代码引起的错误。

https://blogs.sap.com/2014/12/11/my-small-experience-about-how-to-find-the-exact-line-position-which-causes-undefined-is-not-a-function-error/

3. Why my formatter does not work? A trouble shooting example to know how it works

UI5 formatter的原理讲解, 和排错最佳实践。

https://blogs.sap.com/2015/01/03/why-my-formatter-does-not-work-a-trouble-shooting-example-to-know-how-it-works/

4. Something about negative cache error

关于这种negative cache错误信息的处理。

https://blogs.sap.com/2015/06/03/something-about-negative-cache-error/

5. An sample of My Opportunity application extension – hide a given tab in detail page

如何通过扩展(extension)的方式修改标准Fiori应用,例如隐藏某个tab:

https://blogs.sap.com/2015/06/03/an-sample-of-my-opportunity-application-extension-hide-a-given-tab-in-detail-page

6. Cannot open CRM My Opportunity application – how to trouble shoot

看到这种错误消息 Could not open app. Try again later的排错处理。请注意这个错误消息是在UI5一个非常通用的异常处理分支里抛出来的,换言之,有各种各样的可能性会造成这个错误,本文介绍的只是众多种可能的原因之一。但是排错的思路是通用的。

https://blogs.sap.com/2015/06/03/cannot-open-crm-my-opportunity-application-how-to-trouble-shoot/

7. Implementation detail – how a field is hidden in runtime by view modification

UI5 View extension原理讲解: 通过下图的View extension将id为salesTeam的tab的visible属性设置为false, 在运行时就不会显示出这个tab了。但这一切是怎么工作的?

https://blogs.sap.com/2015/06/12/implementation-detail-how-a-field-is-hidden-in-runtime-by-view-modification/

8. How to hide dynamically created UI fields via extension for My Opportunity application

UI5的View extension只能隐藏或者显示那些静态UI元素,即design time时就已经定义在View里的元素。对于运行期通过JavaScript代码动态创建的UI元素则无能为力。

本文介绍了对于后者如果需要动态控制其隐藏还是显示的实现方法。

https://blogs.sap.com/2015/06/17/how-to-hide-dynamically-created-ui-fields-via-extension-for-my-opportunity-application/

9. An example of End to End extension on CRM Fiori application

Fiori端到端的扩展流程详解。这是2015年专门为一个欧洲的Fiori实施伙伴写的。一个很常见的Fiori扩展需求:出于业务需要,客户在标准的数据库表里需要增加新的字段,这些字段需要暴露到Fiori上,能够通过Fiori进行增删查改。

这是一个端到端的扩展,即底层数据库表,OData模型,OData服务实现,和Fiori 标准UI都必须逐一扩展。这个教程分4篇文章,链接如下:

https://blogs.sap.com/2015/06/18/an-example-of-end-to-end-extension-on-crm-fiori-application-part1/

10.  CRM Fiori Application – how is image maintained and displayed in Fiori UI

Fiori图片显示原理介绍

https://blogs.sap.com/2015/06/19/crm-fiori-application-how-is-image-maintained-and-displayed-in-fiori-ui/

11. A Test on Fiori OData request Synchronous mode VS Asynchronous mode

UI5的OData读的API有个参数, 指定按照同步或异步的方式读取数据。这个参数会对应用产生什么样的影响呢?

https://blogs.sap.com/2015/06/19/a-test-on-fiori-odata-request-synchronous-mode-vs-asynchronous-mode/

12. Fiori Busy Dialog – when is it opened and closed

我一度沉迷于Fiori这个美轮美奂的花瓣式动画效果,很想知道它的实现, 就自己调试了一把:

https://blogs.sap.com/2015/06/24/fiori-busy-dialog-when-is-it-opened-and-closed

13. Fiori Icon logic

这又是我刚接触Fiori时问自己的问题之一: 为什么我在源码里写了一个sap-icon://add的字符串,运行期它就被渲染成了一个加号?

https://blogs.sap.com/2015/06/27/fiori-icon-logic/

14. Another potential reason for Fiori timeout error

这是我负责处理过的一个标准Fiori应用的超时问题。把我折腾惨了,有的用户能够重现,有的不能。我花了很长时间同时调试这两个用户,发现程序执行流没有任何差异。我几乎要崩溃了,最后发现问题的根源原来是。。。。。。被队友坑了。

https://blogs.sap.com/2015/07/02/another-potential-reason-for-fiori-timeout-error/

15. Fiori扩展教程

CRM WebClient UI里的两个标准字段Sales Office和Sales Group没有暴露在CRM Fiori的My Opportunities UI上。

这个教程介绍了如何一步步将这两个标准字段放到Fiori UI上。

https://blogs.sap.com/2015/07/11/step-by-step-to-expose-sales-office-and-sales-group-to-my-opportunity-part1/

16. How to quickly locate the code error in application which causes UI stop to load

案例分析: 当加载Fiori应用出现白屏时,一定是某个地方的JavaScript文件执行出错了。

本文介绍了如何快速找到引起错误的JavaScript代码的准确位置。

https://blogs.sap.com/2015/07/16/how-to-quickly-locate-the-code-error-in-application-which-causes-ui-stop-to-load/

17. why there are always multiple read operations after BATCH operation is done successfully

Partner提的问题:为什么SAP发布的标准Fiori应用,在UI上做了某个操作后,从Chrome开发工具里观察到有三个一模一样的HTTP请求发到后台?

https://blogs.sap.com/2015/07/23/why-there-are-always-multiple-read-operations-after-batch-operation-is-done-successfully/

18. How to remove the blue background color of Edit button in footer toolbar

真实的客户需求。默认的编辑按钮具有蓝色的背景色。有个客户不太喜欢,希望通过View扩展的方式将其移除。

最后希望实现这样的效果。

https://blogs.sap.com/2015/08/26/how-to-remove-the-blue-background-color-of-edit-button-in-footer-toolbar/

如果想把背景色改成其他颜色,也是可以的:

https://blogs.sap.com/2015/09/23/how-to-change-the-background-color-of-button-in-footer-area/

19. Step by Step to consume HANA Query view in CRM Fiori

在CRM Fiori应用里消费HANA Studio里创建的Query view

https://blogs.sap.com/2015/08/27/step-by-step-to-consume-hana-query-view-in-crm-fiori/

20. How to monitor the control registration and deregistration

排错需求:需要监控某个UI控件的初始化和析构的准确时间点,来跟踪一些代码bug。

https://blogs.sap.com/2015/10/01/how-to-monitor-the-control-registration-and-deregistration/

21. Regarding Edm.DateTime in Fiori application

处理一个客户ticket时的学习笔记。UI上我们看到的Closing Date是Oct 3, 2015.

从Chrome里看到的数据源是/Date(1443830400000)/。从/Date(1443830400000)/到Oct 3, 2015,背后发生了什么?

https://blogs.sap.com/2015/10/01/regarding-edmdatetime-in-fiori-application/

22. How to trouble shoot field binding issue

字段绑定是一个常见的容易出错的地方,即我们给控件指定了绑定,但是该控件在渲染出来的UI上什么也没显示。本文介绍了排错方法。

https://blogs.sap.com/2015/10/01/how-to-trouble-shoot-field-binding-issue/

23. More details of DatePicker

处理客户ticket的学习笔记,关于DatePicker这个控件的实现细节。

https://blogs.sap.com/2015/10/09/more-details-of-datepicker/

日期格式的讲解专门放在另一篇文章:

https://blogs.sap.com/2015/10/14/dateformat-in-datepicker-control/

24. Some refacting examples with the help of Function.prototype

看了UI5源代码里对Function.prototype使用后出于学习目的的一些模仿:

https://blogs.sap.com/2015/10/13/some-refacting-examples-with-the-help-of-functionprototype/

25. Language related topic for DatePicker

DatePicker控件多语言的支持:

https://blogs.sap.com/2015/10/15/language-related-topic-for-datepicker/

26. How to dynamically change the formatOption of control in the runtime via debugging

为什么上下两个field显示的日期格式不一致?

https://blogs.sap.com/2015/10/19/how-to-dynamically-change-the-formatoption-of-control-in-the-runtime-via-debugging/

27. Contact Support button display logic in Fiori

为什么有的系统Fiori出错后, 错误提示里能看到Contact Support的按钮,

而有的系统看不到?作为强迫症患者,一定用通过调试的方式搞清楚原因。

https://blogs.sap.com/2015/10/19/contact-support-button-display-logic-in-fiori/

28. Two types of popup Dialogs in Fiori

Fiori里两种弹出对话框的实现原理。在处理ticket时,我们经常需要找到准确的抛出这些对话框的代码位置。

https://blogs.sap.com/2015/10/23/two-types-of-popup-dialogs-in-fiori/

29. A Tutorial how I do self-study on a given Fiori control and UI5 framework code behind

我的UI5框架代码自学教程

https://blogs.sap.com/2015/10/26/a-tutorial-how-i-do-self-study-on-a-given-fiori-control-and-ui5-framework-code-behind/

30. An useful Chrome extension – UI5 Inspector

一个有用的Chrome扩展应用: UI5 Inspector

https://blogs.sap.com/2015/12/19/an-useful-chrome-extension-ui5-inspector/

31. Use Fiddle to make modifications on framework js file

Fiddle的另类用途:

ttps://blogs.sap.com/2016/01/18/use-fiddle-to-make-modifications-on-framework-js-file/

32. Currency example – how Smart field works

Smart field工作原理介绍。SAP help上关于Smart field的定义:

Smart controls are a specific category of SAPUI5 controls that have some special features in addition to the standard SAPUI5 features and thus make it easier to use the control in certain scenarios. One important building block of smart controls is the SmartField control that, depending on the OData metadata defined, allows you to renders other controls and, for example, define fields with certain attributes based on the metadata.

XML View中的一个定义例子:

运行时效果如图:

https://blogs.sap.com/2016/03/14/currency-example-how-smart-field-works/

33. 具有value help的Smart field原理介绍

https://blogs.sap.com/2016/03/15/smart-field-with-value-help/

34. 具有超链接的Smart field原理介绍

https://blogs.sap.com/2016/03/15/smart-field-with-smart-link/

35. Chrome Development Tool tips used in my daily work

我在用Chrome开发工具排错时积累的一些使用小技巧

https://blogs.sap.com/2016/03/15/chrome-development-tool-tips-used-in-my-daily-work/

36. How SmartTable works

Smart table工作原理介绍

https://blogs.sap.com/2016/03/16/how-smarttable-works/

37. Create a CRM Service Order Fiori application within a couple of minutes

利用Smart Template框架快速搭建一个Fiori应用, 该应用支持搜索,并且从搜索结果能跳转到明细页面。这个搜索和跳转的功能都不需要通过JavaScript开发的方式实现。

https://blogs.sap.com/2016/03/31/create-a-crm-service-order-fiori-application-within-a-couple-of-minutes/

如果想在明细页面里支持编辑功能,请参考这篇文章:

https://blogs.sap.com/2016/04/10/enable-crm-service-order-application-with-edit-functionality/

如果想支持粗昂见功能,参考这篇文章:

https://blogs.sap.com/2016/05/24/access-the-odata-service-exposed-by-your-cds-view-via-smart-business-tile-in-s4hana-system/

38. An example of Fiori Globalization implementation – the logic of amount value truncation

为什么来自后台同一个值,有的UI控件显示的是1880,有的控件却显示2K? 本文向您揭秘。

https://blogs.sap.com/2016/04/11/an-example-of-fiori-globalization-implementation-the-logic-of-amount-value-truncation/

39. An example of Fiori Globalization implementation – the number format mistery

强迫症患者看到这个差异,又得进行一番调试搞清楚具体在哪行JavaScript代码造成的这种显示差异了。

https://blogs.sap.com/2016/04/11/an-example-of-fiori-globalization-implementation-the-number-format-mistery/

40. Do you understand the logic of HTTP 200 OK and HTTP 304 Not Modified

揭秘为什么同样是HTTP请求,有的收到回复是200,有的是304?

https://blogs.sap.com/2016/04/21/do-you-understand-the-logic-of-http-200-ok-and-http-304-not-modified/

41. My understanding about how object page in Smart Template is rendered

Smart Template框架的渲染原理介绍

https://blogs.sap.com/2016/05/03/my-understanding-about-how-object-page-in-smart-template-is-rendered/

42. How to inject your own XML view into application generated by Smart Template

本文介绍如何在Smart Template框架生成的View(红色区域)里嵌入开发人员设计的自定义View(蓝色区域)。

https://blogs.sap.com/2016/05/03/how-to-inject-your-own-xml-view-into-application-generated-by-smart-template/

43. An example of how to find back button implementation on Smart Template generated application

介绍Smart Template生成的应用里,这个后退按钮的实现原理。

https://blogs.sap.com/2016/05/04/an-example-of-how-to-find-back-button-implementation-on-smart-template-generated-application/

44. More detail about Bootstrap script tag

刚学UI5时我对这个sap-ui-bootstrap字符串很好奇,去掉或者改成其他的值可以么?

https://blogs.sap.com/2016/05/15/more-detail-about-bootstrap-script-tag/

45. A small tip I learn from UI5 Diagnostics tool - a practice of AOP programming

我从这个UI5 Diagnostics工具中学到的知识。

https://blogs.sap.com/2016/05/16/a-small-tip-i-learn-from-ui5-diagnostics-tool-a-practice-of-aop-programming/

46. Build Chart and Table representation via Analytics Path Framework

APF使用介绍:

https://blogs.sap.com/2016/05/21/build-chart-and-table-representation-via-analytics-path-framework/

47. A quick way to find which code has changed the UI5 application page title by debugging

一个ticket的处理记录。

Fiori应用的正常行为,是点击一个Tile后,浏览器会跳转到对应的应用页面,并且窗口显示该应用的名称。

我接到的ticket抱怨的行为是窗口没能正确显示出应用的名称:

https://blogs.sap.com/2016/05/26/a-quick-way-to-find-which-code-has-changed-the-ui5-application-page-title-by-debugging/

48. UI5 debug flag and Local Storage – how is your setting persisted?

这个选项勾上之后,关掉浏览器再打开仍然生效。它的值保存在本地什么位置?

https://blogs.sap.com/2016/06/25/ui5-debug-flag-and-local-storage-how-is-your-setting-persisted/

49. How is OData request routed to Offline data store by Odata offline plugin

SAP Offline OData Plugin的原理介绍之一, 主要介绍JavaScript实现部分。

https://blogs.sap.com/2016/08/04/how-is-odata-request-routed-to-offline-data-store-by-odata-offline-plugin/

50. How is JavaScript code in OData offline plugin delegated to native Java code in Android

SAP Offline OData Plugin的原理介绍之二。以Android平台为例,介绍前台JavaScript代码是如何被投递到后台Java代码去的。

https://blogs.sap.com/2016/08/04/how-is-javascript-code-in-odata-offline-plugin-delegated-to-native-java-code-in-android/

51. How is OData offline store opened in Android platform

SAP Offline OData Plugin的原理介绍之三。介绍了Android平台上OData离线存储打开的实现。

https://blogs.sap.com/2016/08/05/how-is-odata-offline-store-opened-in-android-platform/

52. Step by step to run your Fiori application locally on NodeJS

用nodejs启动Fiori应用

https://blogs.sap.com/2016/12/20/step-by-step-to-run-your-fiori-application-locally-on-nodejs/

如果想用nodejs启动本地launchpad,然后再通过点击tile访问你的应用也是可以的。

https://blogs.sap.com/2016/12/20/how-to-put-your-fiori-application-into-local-launchpad-via-nodejs/

53. How is old SAP GUI transaction embedded into Fiori launchpad

S/4HANA里很多貌似Fiori的应用其实它们并不是用原生的UI5技术实现的,而只是SAPGUI的ABAP应用包了一层Fiori的外壳。本文介绍这种仿Fiori应用的原理。

https://blogs.sap.com/2016/12/21/how-is-old-sap-gui-transaction-embedded-into-fiori-launchpad/

54. Why Adapt UI button is visible in some system but missing in some other system

在S/4HANA的Fiori UI上,用户可以点击Adapt UI进入UI Adaptation模式来对UI的布局做微调。但是在有些系统上,看不见这个Adapt UI按钮。为什么?

https://blogs.sap.com/2016/12/29/why-adapt-ui-button-is-visible-in-some-system-but-missing-in-some-other-system/

55. Fiori launchpad page server side configuration

介绍S/4HANA Fiori Launchpad服务器端的配置原理。

https://blogs.sap.com/2016/12/29/fiori-launchpad-page-server-side-configuration/

56. Why my extension field does not appear in Available Fields list for extension

S/4HANA的FioriUI上用工具创建了一个新的扩展字段:

但是想将其配置到UI上时,从”可用字段”的下拉列表里查找不到该扩展字段,无法添加到UI上。

https://blogs.sap.com/2016/12/30/why-my-extension-field-does-not-appear-in-available-fields-list-for-extension/

57. An example of how cross distribution chain status is updated via draft handling in Fiori application

介绍S/4HANA里Draft handling的实现原理。

https://blogs.sap.com/2017/01/04/an-example-of-how-cross-distribution-chain-status-is-updated-via-draft-handling-in-fiori-application/

58. How to find the backend storage table field for a field in Fiori UI

在SAPGUI里运行的应用,如果我们想知道一个字段的值是存在哪张数据库表的哪个字段,只需要按F1,在弹出的对话框里即可找到。

到了Fiori里,我们仍然有类似的需求,但是F1已经没法用了。本文介绍如何找到Fiori UI上某个字段对应的后台存储。

https://blogs.sap.com/2017/01/06/how-to-find-the-backend-storage-table-field-for-a-field-in-fiori-ui/

59. Useful Chrome Tool chrome://net-internals to monitor http request detail

介绍Chrome这个Net Internals工具的用途。

https://blogs.sap.com/2017/02/06/useful-chrome-tool-chromenet-internals-to-monitor-http-request-detail/

要获取更多Jerry的原创技术文章,请关注公众号”汪子熙”或者扫描下面二维码: