【问题标题】:Angular $location.state() vs history.pushState behaviorAngular $location.state() 与 history.pushState 行为
【发布时间】:2016-01-08 00:13:54
【问题描述】:

我正在尝试构建一个概念验证单页应用程序,该应用程序使用历史 API 来存储视图的状态,这样当用户使用浏览器的后退和前进按钮进行导航时,将显示之前的状态。

这个简单的例子是一系列页面链接和一些显示的值,以显示状态的状态(没有双关语)。

这一切都在一个函数plnkr

基本观点

<div ng-app="testApp">
    <div ng-controller="testCtrl">
        <h1>State Data: {{data.displayText}}</h1>
        <h2>Current Page: {{data.currentPage}}</h2>
        <a ng-click="goToPage(page)" ng-repeat="page in pages" class="page">{{page}}</a>
    </div>
</div>

应用/控制器:

var testApp = angular.module('testApp', ['ngRoute'])
  .config(function($locationProvider) {
        $locationProvider.html5Mode(true);
  });

testApp.controller('testCtrl', ['$scope', '$location', function ($scope, $location) {

    // Hardcode some pages
    $scope.pages = [1, 2, 3, 4, 5, 6, 7, 8, 9];

   // Set initial data
    $scope.data = {
        currentPage: 1,
        displayText: "This is the initial state"
    };

    // Set initial data in state
    $location.state($scope.data);

    // Watch for location changes so we can apply state accordingly
    $scope.$on('$locationChangeSuccess', function (a, newUrl, oldUrl) {
        $scope.data = $location.state();
    });

    // Move between pages
    $scope.goToPage = function (page) {

        $scope.data.currentPage = page;
        $scope.data.displayText = "This is page " + page;

        $location.search("page", page);
        $location.state($scope.data);

        //history.pushState($scope.data, null, '/ThisPage?page=' + page);
    };
}]);

您会注意到注释的 history.pushState() 行。 使用该行而不是上面的 $location.search() 和 $location.state() 行实际上可以像我一样工作和执行'会期望的,但我想使用正确的角度方式让它工作。

编辑: 明确地说,我不是在问我是否应该以有角度的方式来做这件事。我在问什么是让这个工作的正确角度方式。在 $scope.goToPage() 中对 $location 的两次调用不起作用,但对 history.pushState (注释行)的调用确实起作用。我显然错过了如何用纯角度实现这一点的东西,这就是我需要帮助的地方。干杯!

【问题讨论】:

  • 哦,你这个选民,要有建设性,并通过留下有用的评论来帮助改善这一点。

标签: javascript angularjs


【解决方案1】:

根据官方网站上的 AngularJS 文档,使用 $location.search 和 state 而不是 history 绝对没问题。

https://docs.angularjs.org/api/ng/service/$location

如果您使用的是纯 AngularJS,则始终建议您使用 Angular 方式

history.pushState 不是 Angular 代码,它只是一种操作浏览器历史记录的方式,查看链接了解更多详情

https://developer.mozilla.org/en-US/docs/Web/API/History_API

所以我总是希望你使用 $location.search 和 $location.state 而不是 history.pushState

【讨论】:

  • 是的,正如我所说,我想以这种有角度的方式进行操作,但我的实现不起作用 - 寻求指导。
  • 无法打开您的 plunkr 能否请您检查并更新指向您的 plunkr 的链接
  • 我更新了 plnkr 链接,但它似乎对我来说工作正常,即使在隐身和隐私浏览模式下也是如此。
【解决方案2】:

这是我自己发现的解决方法。

无论出于何种原因,当尝试从 goToPage() 方法中设置 $location.state() 时,状态不会被设置。 Angular 会更新 url,但状态数据将为空。

我发现你可以使用 $location.search() 或 $location.path() 来修改 url,然后使用 $location.absUrl() 直接调用 history.pushState()。

这样做有好处的原因是您不必为了得到您想要的 URL 而搞乱字符串解析。 Angular 会处理这个问题,我们只需获取要与 pushState() 一起使用的值。

我不得不认为在 Angular 中有一种方法可以做到这一点,但我还没有找到。

$scope.goToPage = function (page) {
   $scope.data.currentPage = page;
   $scope.data.displayText = "This is page " + page;

   $location.search("page", page);
   history.pushState($scope.data, null, $location.absUrl());
};

【讨论】:

    【解决方案3】:

    每次按下按钮后,您的历史状态对象将设置为 NULL。在代码中注释下一行:

    // $scope.data = $location.state();
    

    或将您的事件注释掉,因为在这种情况下是不必要的

    /*
        Watch for location changes so we can apply state accordingly
        $scope.$on('$locationChangeSuccess', function (a, newUrl, oldUrl) {
            $scope.data = $location.state();
        });
    */
    

    我认为,在那之后你的代码会像一个魅力一样工作。

    【讨论】:

      猜你喜欢
      • 2017-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-02
      • 1970-01-01
      相关资源
      最近更新 更多