【问题标题】:UI5 Router destroying cached viewsUI5 路由器销毁缓存视图
【发布时间】:2017-09-19 15:51:25
【问题描述】:

我有一个主详细信息页面应用程序,我们在其中配置了路由器以在页面之间导航。

App.view.xml

<SplitApp id="rootControl" detailNavigate="onDetailNavigation">
</SplitApp>

manifest.json

"routing": {
                "config": {
                    "routerClass": "sap.m.routing.Router",
                    "viewPath": "master",
                    "controlId": "rootControl",
                    "viewType": "XML",
                    "async":"true"
                },
                "routes": [
                    {
                        ....
                    },
                    ...
                "targets": {}
                   ...

应用程序是简单的员工 CRUD 应用程序,我为路由器配置了 2 个路由,1 个用于创建/编辑,另一个用于显示

如果我从一个视图导航到另一个视图,我需要销毁该视图,例如在页面开始时显示包含所有员工的母版页,而详细信息页面显示员工 1 的显示视图。

我在显示视图上有编辑按钮,按下时我将详细信息页面从显示视图导航到编辑视图,此时我需要从缓存的路由器中销毁显示视图。

如何做到这一点?还是我需要采取不同的方法来解决缓存问题?或者我不应该想到记忆

尝试调用SplitApp的destroy onDetailNavigate

onDetailNavigation : function(oEvent){
            console.log("Split app onDetailNavigation");
            oEvent.getParameter('from').destroy();
        }

下次返回相同视图时会出错

Error: The object with ID __xmlview4 was destroyed and cannot be used anymore.

【问题讨论】:

  • 如果你先remove from 视图然后销毁它会发生什么?如果您下次导航回同一个视图,您会得到同样的错误吗?
  • 让我试一次
  • 做了以下更改var splitApp = this.getView().byId('rootControl'); splitApp.removeDetailPage(oEvent.getParameter('from')); oEvent.getParameter('from').destroy(); 仍然是同样的错误
  • 但如果我不销毁路由器,则路由器具有视图实例但已从 DOM 中删除
  • 我做了一些修改,如下从路由器中删除,这样可以吗?var router = this.getOwnerComponent().getRouter(); for(var view in router._oViews._oViews){ if( router._oViews._oViews[view].sId === oEvent.getParameter('fromId') ) { delete router._oViews._oViews[view]; } }

标签: sapui5


【解决方案1】:

根据 cmets,您销毁视图以节省两个视图分配的内存。我认为这不会带来任何真正的好处。有三种可能的解决方案:

  • 坚持当前的解决方案。
  • 使用单个视图并在显示和编辑片段之间切换。可以在here 找到一个示例。
  • 将单个视图与带有输入字段的表单一起使用。将可编辑属性与模型(例如视图模型)属性绑定,以反映整个表单或每个属性的编辑或显示状态。

&lt;Input value="{applicationModel&gt;/propertyName}" editable="{viewModel&gt;/editable}"/&gt;

我正在使用第三种解决方案的版本。我的应用程序模型(扩展 JSONModel)包含应用程序数据以及控制属性的状态。控制器只需在计算状态的应用程序模型上调用 setEditable。使用这种方法,我可以避免将逻辑分散到应用程序的许多部分。

&lt;Input value="{applicationModel&gt;/propertyName}" editable="{applicationModel&gt;/Attributes/propertyName/editable}"/&gt;

【讨论】:

  • 如果我们将建议项加载到显示视图不需要的输入控件,并且我们必须在控制器中编写大量代码来处理启用和禁用逻辑,所以我的想法是多视图代码与控制、控制器方法有明确的分离
  • 建议项应按需加载。因此,它不是反对组合显示/编辑视图的论据,您只是不要在显示模式下加载建议。如果您担心控制器中的代码过多,请将其移至模型中。
  • 我会感谢您,但要结束这个问题,我将使用@boghyon 评论并回答。感谢您的宝贵意见
【解决方案2】:

由于我的问题是关于从缓存的路由器中销毁视图,因此我遵循了@boghyon 评论并在我的代码中进行了一些更改,如下所示,在详细页面导航后删除页面如下

var splitApp = this.getView().byId('rootControl'); 
splitApp.removeDetailPage(oEvent.getParameter('from')); 

为了从路由器中删除缓存视图,我编写了一些逻辑

var router = this.getOwnerComponent().getRouter(); 
for(var view in router._oViews._oViews){
if( router._oViews._oViews[view].sId === oEvent.getParameter('fromId'){ 
 delete router._oViews._oViews[view]; 
 } 
}

这会破坏视图。

这样做会多次加载视图,这不是我要求的正确方法,我们遵循@matbtt 答案。

感谢两位的宝贵意见。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 2016-12-06
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    相关资源
    最近更新 更多