如何防止用户导航?

时间:2017-11-15 09:49:22

标签: url-routing sapui5

在我的SAPUI5应用程序中,我使用sap.tnt.Toolpage作为主要布局容器。 SideNavigation显示应用程序链接列表,mainContents使用sap.ui.core.routing.Router动态加载。

导航到我正在使用的详细信息页面

var router = sap.ui.core.UIComponent.getRouterFor(this);
router.navTo("MyDetailRoute", {
    detailItemId: oItem.getBindingContext("oDataSourceName").getProperty("DETAILID")
});

这会加载一个详细视图,然后将其控件绑定到我的数据源中的数据。

当我尝试记住用户将其更改保存回服务器时,会出现问题。我基本上想要中断导航以便用户询问a)取消他的更改,b)保存他的更改或c)留在详细页面上。虽然a)和b)易于实现,但我不知道如何防止导航发生。

到目前为止,我已经通过订阅我的观点onBeforeHide来尝试:

var view = this.getView();
var that = this;
view.addEventDelegate({
    onBeforeHide: function (evt) {
        var oModel = that.getModel("oDataSourceName");
        if (oModel.hasPendingChanges()) {
            // How to prevent leaving the page?
        }
    }
});

我尝试过的东西不起作用:

  1. evt.preventDefault();
  2. evt.stopPropagation();
  3. 扔'某事';
  4. 选项3)实际上会阻止导航,但会导致以后出现问题,因为URL会发生变化......

    有没有人有想法?

    编辑:感谢cschuff的回答,我能够让它运转起来。对于将来遇到同样问题的人:

    // In onInit: Subscribe to onBeforeHide in order to un-register event handler for hashchange
    
    onInit: function () {        
        this.getRouter().getRoute("MyDetailRoute").attachPatternMatched(this.onNavigated, this);
    
        var view = this.getView();
        var that = this;
    
        view.addEventDelegate({
            onBeforeHide: function (evt) {
                $(window).off('hashchange');
            }
        });
    }
    
    
    // Then in onNavigate stoppen the router, saving the current window location and subscribing to hashchange (only once)
    // In hashchange use helper variable m_bSelfURLSetting to prevent the function from running when triggered by URL restore (above)
    // In the handler checking for pending changes and either resore the old URL or starting the router again if the user wants to quit or if there are no changes
    
    onNavigated: function (oEvent) {            
    
        this.getRouter().stop();
        this.m_strHref = window.location.href;
        var that = this;
    
        $(window).off('hashchange').on('hashchange', function (e) {
            if (that.m_bSelfURLSetting) {
                that.m_bSelfURLSetting = false;
                return;
            }
    
            var oModel = that.getModel("oDataSourceName");
            if (oModel.hasPendingChanges()) {
                var leave = confirm('There are unsaved changes.\r\n\r\nDo you really want to leave the page?');
                if (!leave) {
                    // re-set the URL
                    that.m_bSelfURLSetting = true;
                    window.location.href = that.m_strHref;
                }
                else {
                    that.getRouter().initialize(false); 
                    oModel.resetChanges();
                }
            } else {
                that.getRouter().initialize(false);
            }
        });
    }
    

    这绝对不是一种值得骄傲的代码......

3 个答案:

答案 0 :(得分:2)

解决方案#1 :您可以使用路由器方法stopinitialize暂时完全停用路由。这将停止侦听url哈希中的更改,从而忽略所有路由触发器。

来自您的控制器:

var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.stop();

// later
// passing true will interpret and navigate to the current hash (since 1.48.0)
oRouter.initialize(true); 

解决方案#2 :使用sap.ui.core.routing.HashChanger事件中断路由。路由器内部使用hashChangedhashReplaced。您也可以尝试sap.ui.core.routing.Router routeMatchedbeforeRouteMatched取消(文档没有提供任何提示)。

解决方案#3 :限制较少的解决方案是仅中断触发该特定视图路由的所有操作。请注意,浏览器返回或手动更改url-hash仍然可以在这里工作(原生JS事件beforeunloadhashchange可能会有帮助。)

BR Chris

答案 1 :(得分:0)

在窗口对象上尝试“onBeforeUnload”事件。

答案 2 :(得分:0)

我只需要解决相同的问题,并且发现有一个API。 但是,仅当该应用程序在Fiori Launchpad中运行时,它才有效。

sap.ushell.Container.setDirtyFlag(bFlag);

这里bFlag是布尔值。如果是true,则用户将必须确认导航。将其设置为false以允许导航而不显示此消息。

只要哈希值发生变化,导航就会中断,因此包含

  • 在您的应用程序中路由
  • 在浏览器的地址栏中更改哈希
  • 在Fiori Launchpad中导航
  • 导航到另一个站点

来源:Implementing Data Loss Protection