Successfully Call history.pushState() from Angular Without Inifinite Digest?

后端 未结 4 1304
野的像风
野的像风 2021-01-17 16:46

Is there a way to call history.pushState() without angular going into an infinite digest loop?

I\'m trying to migrate my app from backend routing to fro

相关标签:
4条回答
  • 2021-01-17 16:47

    I was able to come up with a solution that works with angular 1.2.15.

    The gist of it is to add a target attribute to each link and then use the $location service to change the location.

    Based on the current angular code, anchor tags that have a target attribute are ignored (note that this solution may eventually break).

    To do this, ensure this javascript runs before angular:

    // prevent angular from taking over link clicks until we have frontend routing
    $(document.documentElement).on("click","a",function(event) {
      var elem = $(this), target = elem.attr("target");
      if(!target) {
        elem.attr("target","_self");
        setTimeout(function() {
          elem.removeAttr("target");
        });
      }
    });
    

    After that, configure your location provider to use html5mode:

      angular.module("App", ["App.controllers"]).config([
        "$locationProvider", function($locationProvider) {
          if (history.pushState) {
            $locationProvider.html5Mode(true);
          }
        }
      ]);
    

    Now, in your controller, inject the location service and use it normally:

    angular.module("App.controllers",[]).controllers("SomeController", ["$scope", "$location", function($scope,$location){
        $scope.updateLocation = function() {
          if (history.pushState) {
            $location.path("/new/path/here");
          }
        };
      }]);
    
    0 讨论(0)
  • 2021-01-17 16:56

    This is what we do in an Angular 1.2.16 app based on this github comment: https://github.com/angular/angular.js/issues/3924#issuecomment-48592773

    $location.url(myNewUrl);
    $location.replace();
    $window.history.pushState(null, 'any', $location.absUrl());
    

    This code is part of a controller. I'm using it to add a query param to the url without wanting to reload the page. It works in our case.

    0 讨论(0)
  • 2021-01-17 17:00

    I recently encountered a variation of this problem myself and none of the answers here worked for me in isolation. history.pushState was defined, but only worked if called from the console. I was able to come up with a solution by consolidating a few of the answers here. Here is the code I used to solve this problem:

    // Configure $locationProvider html5Mode
    app.config(['$locationProvider', function($locationProvider) {
        $locationProvider.html5Mode({ enabled: true, requireBase: false, rewriteLinks: false });
    }]);
    
    // In controller
    $window.history.pushState(null, 'Page Title', '/some_new_url');
    

    I'm running Angular 1.5.5.

    0 讨论(0)
  • 2021-01-17 17:03

    Use the rewriteLinks option on the $locationProvider html5Mode object:

        pageModule.config(function($locationProvider) {
            $locationProvider.html5Mode({
                enabled: true,
                requireBase: false,
                rewriteLinks: false
            });
        });
    

    Afterwards, you should be able to use the $location service properly, such as:

        this.$location.path("/mynewpath");
    
    0 讨论(0)
提交回复
热议问题