通过使用组件容器在多个应用程序中重用应用程序

Reuse application in multiple applications by using component container

我在组件容器中引用的应用程序在特定情况下未加载。知道我做错了什么或者我可以做些什么来解决我的问题吗?

这些是我为出现问题而采取的步骤:

第 1 步:在工作列表中打开弹出窗口

第 2 步:在工作列表中按 'a' 导航到详细信息,然后在详细信息中打开弹出窗口

第 3 步:按左上角的 'back-arrow' 导航到工作列表(见上图),然后再次打开工作列表中的弹出窗口。

我有 3 个应用程序:worklist-app、detail-app、popover-app。

弹出窗口应用程序通过使用组件容器包含在我的工作列表和详细信息应用程序中(弹出窗口的 ID 在工作列表和详细信息应用程序中不同):

<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core">
    <ResponsivePopover afterClose="destroyPopover" class="sapUiPopupWithPadding" id="popover--id1" placement="Left">
        <content>
            <core:ComponentContainer name="name.space.app" component="appname" propagateModel="true">
            </core:ComponentContainer>
        </content>
    </ResponsivePopover>
</core:FragmentDefinition>

在我的 worklist-app 和 detail-app 的 Component.js 中,我使用以下方式注册了我的 popover-app:

jQuery.sap.registerModulePath("name.space.app", "/sap/bc/ui5_ui5/sap/appname");

在我的 worklist-app 和 detail-app 的 onExit-method 中,我销毁了 popover 以防止 duplicate-id 错误。

当我打开工作列表中的弹出窗口时,弹出窗口正确打开。 当我在 detail-app 中打开弹出窗口时,弹出窗口正确打开。

当我在detail-app的时候,我点击左上角的'back-arrow',

** 我导航回工作列表。如果那时我想打开弹窗,弹窗打开了,但里面什么也没有显示。**

我希望弹出窗口像在步骤 1 中一样可见。

打开弹出窗口的代码:

if (!this._oPopover) {
            this._oPopover = sap.ui.xmlfragment("name.space.popover", this);
            this.getView().addDependent(this._oPopover);
            this._oPopover.setBusy(true);
}

this._oPopover.openBy(oEvent.getSource());

关闭弹出窗口的代码:

if(this._oPopover) {
   this._oPopover.destroy();
}

我没有收到任何错误,所以我不知道如何调试实际发生的事情。

我注意到我进入了我的 popover-application 的 App.controller,但在那之后他没有进入我的 popover-view 中指定的控制器的 onInit()。

有人曾经遇到过同样的问题,或者有人知道是什么导致了这种行为或者我可以做些什么来解决我的问题?

在此先感谢您的帮助!

我以前也遇到过类似的问题,通过将我的onInit代码移到默认路由方法的onRouteMatched函数中解决了这个问题。这对我有用。

...
     onInit: function () {

            this.getRouter().getRoute("home").attachPatternMatched(this._onRouteMatched, this);


        },


        _onRouteMatched: function (oEvent) {
          //PUT your code here
        },

第一次点击时效果很好,但第二次点击时,!this._oPopover 为假,您尝试打开一个 invalid/destroyed 片段。

if (!this._oPopover) {
   //entered only on first click,
   //even after leaving app to a launchpad and navigating back in the app
   this._oPopover = sap.ui.xmlfragment("name.space.popover", this);
   this.getView().addDependent(this._oPopover);
   this._oPopover.setBusy(true);
}

this._oPopover.openBy(oEvent.getSource());

关闭弹出窗口的代码:

if(this._oPopover) {
   this._oPopover.destroy();
   //Popover fragment is destroyed, but this._oPopover still holds an object
   //reset also variable here
  this._oPopover = undefined;
}

通常您不必销毁该片段,只需关闭它并再次重新打开它,因为您将它保存在 this._oPopover 中,这样它就不会在每次点击时再次初始化。

在打开弹出窗口的控制器的 onInit() 中将 this._oPopover 声明为 initial/undefined 可确保在初始化视图时片段也被初始化。

编辑关于您的评论:

通常一个片段没有生命周期方法并且被实现为the following in a kind of Singleton设计模式。

如果你有一个完整的自己的应用程序包裹着你的弹出片段(这就是我的理解),我不确定生命周期方法在你的情况下是如何处理的,当你只引用一个片段而不使用视图时和导航。在一个视图中,onBeforeRendering() 总是在 重新渲染 时调用,这与只调用一次的 onInit() 相反,参见 this blog post.

尽管如此this._oPopover = undefined;,当销毁片段时应该修复你不是最佳实践的方法?

所以我弄清楚了应用程序不再加载的原因。在工作列表(执行返回导航时的端点)中,我实现了一个应用程序状态以存储先前设置的过滤器。

appstate 是通过 URL 中的键存储的,因为这个键,manifest 在尝试打开后无法映射弹出应用程序目标。

我已经通过调整我的 popover 应用程序清单中的路由解决了这个问题:

"routes": [
    {
        "pattern": ":?query:",
        "name": "popoverapp",
        "target": [
                "popoverapp"
        ]
    }
],