简体   繁体   English

在PushState单页应用程序中将URL片段(#)用于模式视图

[英]Using URL fragment (#) for modal views in a pushState single-page app

We're using Backbone.Router in a pushstate-only mode, so all our client routes are hash-less . 我们在仅推送状态模式下使用Backbone.Router ,因此我们所有的客户端路由都是无哈希的
However, we're facing a difficulty with implementing modal views in our app. 但是,我们在应用程序中实现模态视图时遇到了困难。

The challenge is the following: 挑战如下:

  • We want Back button to hide the current modal view (so we need it to have a URL); 我们希望“后退”按钮隐藏当前的模式视图(因此我们需要它具有一个URL);
  • We want Forward to show it again without redrawing the whole app; 我们希望Forward再次显示它而不重绘整个应用程序;
  • We want to be able to show modals “on top of” any existing route and not just on one page; 我们希望能够在任何现有路线的顶部而不是仅在一页上显示模式。
  • We want to be able to make links that immediately show a specific modal (such as login modal view). 我们希望能够建立立即显示特定模式的链接(例如登录模式视图)。

In other words, we want modal views to be represented in history . 换句话说, 我们希望在历史中代表模态视图

Our first attempt was to use URL like /login for login modal and handle them specifically in route handler. 我们的第一个尝试是使用/login类的URL进行登录模式,并在route处理程序中专门处理它们。 When we're on /otherpage , opening modal would navigate to /login , and, when modal is closed, navigate again to /otherpage . 当我们在/otherpage ,打开模式将导航到/login ,而当模式被关闭时,再次导航到/otherpage

However, this has a very major problem: URL like /login doesn't “know” over which view it should be drawn, so we have to redraw everything when pressing Back and Forward. 但是,这有一个非常主要的问题:像/login这样的URL并不“知道”应该绘制哪个视图,因此在按Back and Forward时,我们必须重新绘制所有内容。

This actually makes sense: Login modal over Home screen should have different URL from Login modal over Other Page. 这实际上是有道理的:“主页”屏幕上的登录模式应具有与“其他页面”上的登录模式不同的URL。

My second thought was that maybe we can use hashes for indicating current modal view : 我的第二个想法是, 也许我们可以使用散列来指示当前的模态视图

/
/#login
/otherpage
/otherpage#login

This makes the routing handler simple: 这使路由处理程序变得简单:

  • First, draw the actual views based on matched route, just like we did before. 首先,像之前一样,根据匹配的路线绘制实际视图。
  • After that, if hash is present, display a modal view on top. 之后,如果存在哈希,则在顶部显示模式视图。

This also fits with the idea of hash being a “fragment” of the visible document. 这也符合哈希是可见文档的“碎片”的想法。 (Yes, apps are not documents , bla bla bla. We still want them to be addressable.) (是的, 应用不是文档 ,等等。我们仍然希望它们能够被寻址。)

Are there any inherent problems in this approach? 这种方法有什么内在的问题吗?
Is there a better approach satisfying our conditions? 有没有更好的方法可以满足我们的条件?

If I understand your problem correctly, I don't believe you need a hash and I do believe you can implement the modal by simply adding more routes. 如果我正确理解了您的问题,那么我不认为您需要一个哈希,并且我相信您可以通过简单地添加更多路由来实现模式。 If you need to support a login modal over other existing routes, simply add another route that adds login to the end. 如果需要在其他现有路由上支持登录模式,只需添加另一条将登录添加到末尾的路由即可。 Here would be an example: 这是一个示例:

var Login = Backbone.Model.extend({
    closeLogin: function () {
        this.set({ open: false }, { silent: true });
        this.trigger('loginClosed');
    }
});

var LoginView = Backbone.View.extend({
    el: '#loginModal',     
    initialize: function () {
        this.listenTo(this.model, 'loginClosed', this.closeLogin);
    },
    closeLogin: function () {
        // do whatever you would normally do to close the modal
    }
});

var Router = Backbone.Router.extend({
    routes: {
        '/login': 'defaultRouteLogin',
        '': 'defaultRoute',
        'otherpage/login': 'otherPageRouteLogin',
        'otherpage': 'otherPageRoute'
    },
    defaultRoute: function () {
        // defaultRoute behaviors
        this.login.closeLogin();
    },
    defaultRouteLogin: function () {
        // defaultRoute behavior
        // instantiate login modal
    },
    otherPageRoute: function () {
        // otherPageRoute behavior
        this.login.closeLogin();
    },
    otherPageRouteLogin: function () {
        // otherPageRoute behavior
        // instantiate login modal
    },
    initialize: function () {
        this.login = new Login();
        this.loginView = new LoginView({ model: this.login });
    }
});

To support back-button behavior, use a method that closes your login modal on every route where you could open your modal. 要支持后退按钮行为,请使用一种方法来关闭您可以打开模式的每条路径上的登录模式。 Be sure to order the routes correctly. 确保正确订购路线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在单页pushState Web应用程序中模拟画外音页面加载 - Simulate Voiceover page load in single-page pushState web application 使用服务器端和客户端渲染的单页ReactJS应用程序? - Single-page ReactJS app using both server-side and client-side rendering? 单页网页应用中的Google Analytics跟踪问题 - Google Analytics trackevent in single-page web app 使用AngularJS及其RouteProvider的纯本地单页应用程序 - Pure Local Single-Page App With AngularJS and its RouteProvider 在单页Web应用程序中一次仅显示某些形式 - showing only certain form at a time in single-page web app 在单页应用上管理JavaScript的最佳实践 - Best practices managing JavaScript on a single-page app Chrome扩展程序默认html或404(用于单页应用程序路由) - Chrome extension default html or 404 (for single-page app routing) WordPress驱动的单页面应用程序具有通用JavaScript - WordPress-driven, single-page app with universal JavaScript 使单页Web应用的执行速度更快 - make single-page web app perform faster 将单页 Angular 应用程序模板集成到 Sails.js 中 - Integrating a Single-Page Angular App Template into Sails.js
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM