Angular $ location.state()vs history.pushState行为

时间:2016-01-08 00:13:54

标签: javascript angularjs

我正在尝试构建一个概念验证单页面应用程序,它使用历史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(注释行)的调用确实有效。我显然错过了一些如何用纯粹的角度实现这一点的东西以及我需要帮助的东西。干杯!

3 个答案:

答案 0 :(得分:0)

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

https://docs.angularjs.org/api/ng/service/ $位置

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

history.pushState 不是Angular代码,它只是一种如何操作浏览器历史记录结帐链接的更多详细信息

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

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

答案 1 :(得分:0)

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

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

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

这有利的原因是您不必乱用字符串解析来获取所需的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());
};

答案 2 :(得分:0)

按下每个按钮后,您的历史状态对象将设置为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();
    });
*/

我认为,之后你的代码就像魅力一样。