【问题标题】:$state.go is not changing the Url$state.go 没有改变 URL
【发布时间】:2016-04-03 03:36:15
【问题描述】:

我正在使用带有 ui-router 的 Angular.js 1.3。 我有 3 页,page1.html、page2.html、page3.html。

当用户点击 page1 时,page2 将打开,但我想保存页面 1 的滚动状态,即用户点击之前所在的位置,以便在点击后退按钮后,他会进入相同的滚动状态。

为了解决这个问题,我在 iframe 中的 page1.html 上打开 page2.html,并为其提供绝对位置以显示在 page1.html 上,我正在使用:

history.pushState({}, '', '/page2.html');

更改网址。此实现工作正常。

现在当用户点击 page2.html 上的链接时,它应该会打开 page3.html,就像我使用的普通链接一样:

$state.go("page3")

现在的问题是状态变化,page3.html 加载,但 url 仍然是 /page2.html,url 没有改变。

我什至尝试过:

history.pushState({}, '', '/page3.html');

仍然 url 没有改变。任何人都知道为什么会这样。

【问题讨论】:

  • 我不确定这是否可行。但我猜你在Iframe 这就是为什么它不改变这个网址。当你在第2页时,你能试试eval吗?可能是parent.eval($state.go("page3")) 这样的东西。
  • 你能发一个 JSFiddle 吗?
  • 对不起,我不能在 jsfiddle 上发布它。但是,是的,我可以理解链接在 iframe 中,这就是为什么它没有改变 url(可能)。但是js代码运行正常,history.pushState在运行(Js源码调试器),但是对url没有影响。将深入了解 iframe。

标签: javascript angularjs url browser-history pushstate


【解决方案1】:

如果您更改 Angular 的默认行为,则无法更改 url。 url中hash后的部分会自动改变。您没有更改 url,因为您强制浏览器使用 /somepage.html

试试 /#somepage.html 之类的东西

注意这里添加的哈希(#)。

【讨论】:

    【解决方案2】:

    尽管您尝试实施的解决方案非常有创意,但我真的会选择另一个方向。

    您有多种选择,所有这些都依赖于在某处缓存滚动位置。例如:

    var scrollTopData = {};
    
    function changeState (toState) {
        var currentStateName = $state.current.name;
        scrollTopData[currentStateName] = window.scrollY;
        $state.go(toState);
    }
    

    那么问题仍然是如何处理您缓存的滚动位置。 $state.go 返回一个承诺,因此解决方案是:

    var scrollTopData = {};
    
    function changeState (toState) {
        var currentStateName = $state.current.name;
        scrollTopData[currentStateName] = window.scrollY;
    
        $state.go(toState).then(function () {
            if (toState in scrollTopData) {
                window.scrollTo(0, scrollTopData[toState]);
            }
        });
    }
    

    根据你的实现,你也可以使用asgoth的答案:

    我以前没用过,但是 angular 有一个$anchorScroll 服务。至于重新加载数据,你可以使用$cacheFactory缓存它,或者将数据存储在更高的范围内。

    另一种解决方案是使用stateChangeEvent。例如:

    $rootScope.$on('$stateChangeSuccess',
        function (event, toState, toParams, fromState, fromParams) {
            // Do magic
        }
    );
    

    我的建议是使用$state.go 返回的承诺。

    【讨论】:

    • 是的,感谢您提供此信息。但是我的项目涉及无限滚动:在第一次加载时,API 提供第一个 20 产品,然后滚动下一个 20 来,所以如果用户向下滚动到第三次并点击项目,然后点击返回按钮,API 会从开始被调用,所以保存滚动点没有用,因为数据不可用。我当前的解决方案在顶部显示点击的页面,因此在 popstate 上删除它会再次保存 API 命中并保持与以前相同的位置。
    • 嗯,在回答之前,这些信息会派上用场的 :) 无论如何,这个概念保持不变,但有一个补充:您可以将您在加载更多文章时使用的页码放入散列路径。加载无限滚动页面时,检查页码,加载所有内容并将窗口滚动到最后一个已知的滚动位置。
    猜你喜欢
    • 1970-01-01
    • 2017-04-14
    • 1970-01-01
    • 2022-06-14
    • 2015-05-20
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多