自定义控件:"Lifecycle-Method" 更新聚合时

Custom Control: "Lifecycle-Method" when aggregation is updated

我正在创建一个简单的自定义控件:

sap.ui.define([
  "sap/ui/core/Control"
], function(Control) {
  "use strict";

  return Control.extend("my.control.SvgVisualizer", {
    metadata: {
      properties: {
        width: {
          type: "sap.ui.core.CSSSize",
          defaultValue: "100%"
        },
        height: {
          type: "sap.ui.core.CSSSize",
          defaultValue: "100%"
        }
      },
      aggregations: {
        elements: {
          type: "my.control.Element",
          multiple: true,
          singularName: "element"
        }
      }
    },

    renderer: {
      apiVersion: 2,
      render: function(oRm, oControl) {
        oRm.openStart("svg", oControl.getId())
          .attr("viewBox", oControl._sViewBox)
          .attr("width", oControl.getWidth())
          .attr("height", oControl.getHeight())
          .openEnd();
        oRm.close("svg");
      }
    }
  });
});

基本上,它可以用于将带有聚合的 svg 内容实现到 SAPUI5 中。 在 renderer 函数中创建 svg (html) 元素时,我需要一个 viewBox.

我想根据聚合 elements 中控件的属性计算 viewBox 的值。如果有 elements.

的负载,计算可能会非常繁重

我的问题是我应该在哪里计算viewBox 属性。当聚合 elements 改变时需要重新计算(所以 init 是不够的)但是不需要每次调用 renderer 函数时都重新计算。

将处理程序附加到 constructor 中的聚合绑定是最好的方法:this.getBinding("elements").attachChange(...)

可以覆盖所有聚合修饰符,如 addElementremoveElement、...等并在那里重新计算。 但我建议在 onBeforeRendering 挂钩中对 elements 聚合实施某种变化检测,并仅在聚合发生变化时才执行计算。这样您就不必担心是否正确覆盖了所有修饰符并且在一个地方实现了。例如:

onBeforeRendering: function () {
    var currElements = this.getElements();
    var recalculate = false;

    if (!this._oldElements) {
        recalculate = true;
    } else if (this._oldElements.length !== currElements.length) {
        recalculate = true;
    } else if (... another condition that should trigger recalculation) {
        recalculate = true;
    }

    if (recalculate) {
        this._sViewBox = ...;
        this._oldElements = currElements;
    }
    
}