如何将函数传递给自定义控件

How to pass a function to custom control

我对 UI5 中的自定义控件有疑问。假设我想在自定义控件中使用格式化程序函数(请参阅下面的代码片段)。我的一位同事坚持认为自定义控件应该尽可能通用(例如,能够以您需要的任何方式指定带有逗号、空格和换行符的文本)。因此我的想法是将格式化程序函数传递给自定义控件。是否可行,如果可行,如何实现?

sap.ui.define([
  "pr/formatter/Formatter",
  "sap/m/Popover",
  "sap/m/Text"
], function(Formatter, Popover, Text) {
  "use strict";

  return Text.extend("pr.control.TextWithPopover", {
    metadata: {
      aggregations: {
        _popover: {
          type: "sap.m.Popover",
          multiple: false,
          visibility: "hidden"
        }
      }
    },

    init: function() {
      const popover = new Popover({});
      this.setAggregation("_popover", popover);
    },

    setText: function(text) {
      if (this.getProperty("text") !== text) {
        // How to make it generic? 
        const formattedText = Formatter.formatCommaListToNewLine(text);
        const contentToAdd = new Text({ text: formattedText });
        contentToAdd.addStyleClass("popoverContent");
        // ...
      }
    },

    renderer: "sap.m.TextRenderer",
  });
});

UI5 在 1.46(Commit) 中引入了标准类型 "function"sap/ui/base/DataType,它允许 ManagedObject 属性接收函数作为它们的值。

控制

return ControlToExtend.extend("MyControl", {
  metadata: {
    properties: {
      /**
      * This function will contain foo and bar as parameters.
      * Applications should return xyz.
      */
      doSomethingWith: {
        type: "function",
      },
    },
  },
  // ...
  getXYZ: function(/*...*/) {
    const doSomethingWith = this.getDoSomethingWith(); // function from the application
    if (typeof doSomethingWith == "function") {    
      const [foo, bar] = [/*...*/];
      return doSomethingWith(foo, bar);
    } else {
      /*default behavior*/;
    }
  },
});

申请

<MyControl doSomethingWith=".myControllerMethod" /> <!-- or -->
<MyControl doSomethingWith="some.globally.available.function" /> <!-- or -->
<!-- Since 1.69: -->
<MyControl
  xmlns:core="sap.ui.core"
  core:require="{
    'myRequiredFunction': 'mynamespace/myApplicationFunction'
  }"
  doSomethingWith="myRequiredFunction"
/>

注: XMLTemplateProcessor (XML-view / -fragment) 支持function 仅自 1.56 起的属性。 (Commit)

myApplicationFunction: function(foo, bar) {
  // create and return xyz however the application wants;
},

这样,控件就不会硬依赖于应用程序,同时保持允许更改默认输出或行为的灵活性。


上述选项是 UI5 中减少紧耦合的众多解决方案之一。另一种解决方案是添加一个控件 属性,然后应用程序可以通过绑定和格式化程序对其进行操作。

通常,控件(或控件库)和控件使用者(例如应用程序)应始终独立开发;在两者之间有一个接口(例如 MenagedObjectMetadata)并且控件仍然对扩展开放,但没有透露它们是如何在内部实现的。