在 Fiori 中将对话框定位在屏幕中央

Position the dialog at the center of the screen in Fiori

我有一个 SAPUI5 Fiori 应用程序。

我使用主题 sap_fiori_3 作为基本主题。

我定制了这个主题,只给主题贴了一张背景图。

有趣的是,当我激活这个自定义主题 (与原始 sap_fiori_3 主题相比,它只有一个额外的背景图像),对话框没有居中在我的应用程序中了。 该对话框由 sap.m.dialog class 组成。

我写了一小段代码来使对话框居中,如下所示:

onAfterDialogOpen: function(oEvent){
        var oDialog = oEvent.getSource(),
            $Dialog = oDialog.$(),
            oPosition = $Dialog.position(),
            iTop = oPosition.top,
            iLeft = oPosition.left,
            iDialogWidth = $Dialog.width(),
            iDialogHeight = $Dialog.height(),
            iScreenWidth = sap.ui.Device.resize.width,
            iScreenHight = sap.ui.Device.resize.height,
            iNewTop = Math.floor((iScreenHight-iDialogHeight)/2),
            iNewLeft = Math.floor((iScreenWidth-iDialogWidth)/2);
        if(Math.abs(iNewLeft-iLeft) > 10 & Math.abs(iNewTop-iTop) > 10){    
            $Dialog.offset({top: iNewTop, left: iNewLeft});
        }
    },

但这不是一个好的解决方案。为什么?因为它在我的屏幕上做出如下动作:

现在的问题是,如何在没有 Java 脚本的情况下通过设置或其他一些技巧使对话框居中,当对话框打开时,它已经居中。

请注意,无法使用 onBeforeOpen 事件,因为我需要对话框的大小和位置!

我终于找到问题的根源了。看来SAP的Theme Designer有问题,部分主题代码没有传输到导出的文件中。

当我使用主题设计器自定义主题时,不仅出现了上述错误,而且在使用自定义主题的fiori launchpad 中部署的应用程序中还出现了一些其他奇怪的行为。但是,我们在WEB IDE 开发时没有那些错误。

因此我只需要自定义以下项目:

  1. 背景图片
  2. 徽标
  3. 图标

我尝试使用像 sap_fiori_3 这样的标准主题并解决设置这些属性的问题。

因此,对于前两期,我使用了 CSS hack:

div.sapUShellFullHeight {
    background-image: url(../images/myBackgroundImage.svg);
    background-repeat: no-repeat;
    background-size: contain;
    background-position: right;
}

a#shell-header-logo > img#shell-header-icon {
    content:url(../images/logo.svg);
}

对于 favicon 我使用了 promise 解决方案。请注意 fiori launchpad 每次在应用程序之间切换时 fiori 都会重置 favicon,所以我使用 JavaScript promise 来设置它。

// Set the favicon dynamically to get read of blinking 
function waitForElementAppear(selector) {
  return new Promise(function(resolve, reject) {
    var element = document.querySelector(selector);
    if(element) {
      resolve(element);
      return;
    }
    var observer = new MutationObserver(function(mutations) {
      mutations.forEach(function(mutation) {
        var nodes = Array.from(mutation.addedNodes);
        for(var node of nodes) {
          if(node.matches && node.matches(selector)) {
            observer.disconnect();
            resolve(node);
            return;
          }
        };
      });
    });
    observer.observe(document.documentElement, { childList: true, subtree: true });
  });
}
//
function waitForElementRemoved(selector) {
  return new Promise((resolve) => {
    var element = document.querySelector(selector);
      if(!element) {
          resolve();
          return;
      }
      var observer = new MutationObserver((mutations, observer) => {
        for (const mutation of mutations) {
          for (const removedNode of mutation.removedNodes) {
            if (removedNode === element) {
              observer.disconnect();
              resolve();
            }
          }
        }
      });
      observer.observe(element.parentElement, { childList: true });
    });
}
//  
function changeFavIcon(selector) {
        waitForElementAppear(selector).then(function(element) {
        element.setAttribute("href", "icon/favicon.ico");
        waitForElementRemoved(selector).then(function() {
            changeFavIcon(selector);
        });
    });
};
changeFavIcon("link[rel='shortcut icon']");

它会递归检查 favicon 何时被注入然后它会设置它的 href 并且一旦它被删除,这个函数就会观察下一次注入!

据我所知,有人可能会说为什么不使用 sapui5 其设置 favicon 的原始解决方案,如下所示:

jQuery.sap.setIcons({
            'phone': '/images/cimt-logo.png',
            'phone@2': '/images/cimt-logo.png',
            'tablet': '/images/cimt-logo.png',
            'tablet@2': '/images/cimt-logo.png',
            'favicon': '/icon/favicon.ico',
            'precomposed': true
        });

我必须说它在我的情况下不起作用!