【问题标题】:History API/Angular: how to go back to predetermined URLHistory API/Angular:如何返回到预定的 URL
【发布时间】:2015-04-20 22:30:33
【问题描述】:

我在使用 Angular UI 路由器的 Angular 应用程序中要求从一个屏幕 (URL) 返回到之前访问过的屏幕 (URL)。有几个屏幕 (URL) 可以访问目标页面。虽然它不像简单的history.back() 操作那么简单,因为我有几个临时状态可以以任何顺序和任何数量出现。为了解决这个问题,我在 Angular $location 服务周围实现了一个包装器,如下所示:

(function () {
    'use strict';
    angular
        .module('myApp')
        .factory('locn', ['$location', '$state',
            function ($location, $state) {
                var states = [];
                return {
                    go: function (url) {
                        $location.path(url);
                    },
                    pushandgo: function (state, params) {
                        states.push({ name: $state.current.name, params: $state.params });
                        $state.go(state, params);
                    },
                    push: function (url) {
                        states.push(url);
                    },
                    pop: function () {
                        var state = states.pop();
                        $state.go(state.name, state.params);
                    },
                    search: function (searchDict) {
                        $location.search(searchDict);
                    }
                };
            }]);

})();

如您所见,这会将状态存储在locn 服务的javascript 局部变量中。我可以调用pushandgo,这意味着当我随后调用pop 时,我可以返回到我来自的页面(无论是哪个页面)。

这可以正常工作,直到用户在目标页面上刷新页面。

重新创建的 states 数组会丢失所有先前推送的状态。

除了使用 cookie 或本地存储(糟糕)之外,我正在努力想出一个很好的解决方案。

【问题讨论】:

    标签: javascript angularjs browser-history html5-history


    【解决方案1】:

    使用$locationProvider 支持深度链接。文档相当稀疏,但它允许在临时状态之间切换,以及链接回临时状态的页面刷新。如果你想使用 HTML5 历史模式,你可以使用$locationProvider.html5Mode(true)

    【讨论】:

    • 感谢您的回答。不确定启用 html5mode 对我的困境有何帮助?
    【解决方案2】:

    我找到了使用 cookie 或本地存储的更可口的解决方案 - 会话存储!

    我的 locn 服务现在看起来像这样。

    (function () {
        'use strict';
        angular
            .module('csApp')
            .factory('locn', ['$location', '$state', '$window',
                function ($location, $state, $window) {
                    return {
                        go: function (url) {
                            $location.path(url);
                        },
                        pushandgo: function (state, params) {
                            $window.sessionStorage.setItem("prev", JSON.stringify({ name: $state.current.name, params: $state.params }));
                            $state.go(state, params);
                        },
                        pop: function () {
                            var state = JSON.parse($window.sessionStorage.getItem("prev"));
                            $window.sessionStorage.removeItem("prev");
                            $state.go(state.name, state.params);
                        },
                        search: function (searchDict) {
                            $location.search(searchDict);
                        }
                    };
                }]);
    
    })();
    

    【讨论】:

    • 我仍然认为你应该考虑使用 Angular 内置的 $locationProvider 服务,而不是自己滚动。
    • @TuiPopenoe 我在 $locationProvider 上看不到任何可用的功能来让我回忆历史中的某个项目——不仅是前一页,还有任何给定的前一页。 $locationProvider 的目的不是为如何存储 URL 提供配置实用程序吗?如果你提供一个例子,我可能会更容易理解?
    【解决方案3】:

    我知道这是一个老问题,但我已经为这个问题和其他历史问题开发了一个简单的解决方案:

    https://github.com/adamantioengcomp/ada-hsitory

    这个方法用它的url参数堆叠状态变化,所以它模拟了Android中屏幕之间的Stack导航。这可以防止导航时出现不良行为。

    通过安装此模块并注入服务“历史”,有 3 个有用的方法:

    History.back() -> 返回上一个屏幕(并从堆栈中删除最终屏幕)

    History.backTo(route) -> 返回特定路线并清除该路线之前的历史记录(请参阅下面的注释)

    History.clear() -> 清除所有历史记录。

    History.back()History.backTo() 方法都可以接收对象作为参数,并将参数放入 URL。

    例子:

    History.back({productId:1}) -> 返回上一个屏幕,所有原始参数加上参数productId = 1; 这个参数可以带$location.search()

    注意:此模块使用另一个历史对象,不影响浏览器历史记录

    【讨论】:

      猜你喜欢
      • 2017-10-31
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 2016-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多