Turn off URL manipulation in AngularJS

前端 未结 5 991
旧时难觅i
旧时难觅i 2020-11-27 04:07

I\'m trying to write my first web-app with Angular.

In the normal mode (html5Mode off), Angular forces the address\'s hash part to look like a \"path\" (adding a lea

相关标签:
5条回答
  • 2020-11-27 04:35

    Not sure of the side effects of this, but it gets the job done. Note that it will disable all location manipulation from the angular app, even if intended.

    angular.module('sample', [])
        .config( ['$provide', function ($provide){
            $provide.decorator('$browser', ['$delegate', function ($delegate) {
                $delegate.onUrlChange = function () {};
                $delegate.url = function () { return ""};
                return $delegate;
            }]);
        }]);
    

    ES6 variant:

    angular.module('sample', [])
        .config(["$provide", $provide => {
            $provide.decorator("$browser", ["$delegate", $delegate => {
                $delegate.onUrlChange = () => { };
                $delegate.url = () => "";
    
                return $delegate;
            }]);
        }]);
    

    Tested in Chrome 30, IE9, IE10.
    Inspired by https://stackoverflow.com/a/16678065/369724

    0 讨论(0)
  • 2020-11-27 04:39

    The workaround from @greg.kindel (the accepted solution) didn't work for me. It threw lots of errors about an infinite digest loop. I'm using Angular 1.5.8.

    I was able to adjust that workaround to the following to get things working. I hope it saves someone else grief.

    angular.module('sample', [])
      .config(['$provide', function ($provide) {
        $provide.decorator('$browser', ['$delegate', '$window', function ($delegate, $window) {
          $delegate.onUrlChange = function () {};
          //
          // HACK to stop Angular routing from manipulating the URL
          //
          // The url() function seems to get used in two different modes.
          //
          // Mode 1 - Zero arguments
          // There are no arguments given, in which case it appears that the caller is expected the
          // browser's current URL (a string response).
          //
          // Mode 2 - Three arguments
          // It receives three arguments (url, some_boolean, null).  It seems the caller is expecting
          // the browser's URL to be updated to the given value.  The result of this function call is
          // expected to be the $delegate itself, which will subsequently get called with no arguments
          // to check the browser's URL.
          //
          // The Hack:
          // We save the URL so that we can lie to the caller that the URL has been updated to what was
          // requested, but in reality, we'll do nothing to alter the URL.
          //
          var savedUrl = null
          $delegate.url = function (url, ...args) {
            if (!!url) {
              savedUrl = url;
              return $delegate;
            } else {
              return !!savedUrl ? savedUrl : $window.location.href;
            }
          };
          return $delegate;
        }]);
      }])
    
    0 讨论(0)
  • 2020-11-27 04:43

    If I recall correctly, Angular's routing is not obligatory, but then you must take care of reloading controllers, views, etc.

    0 讨论(0)
  • 2020-11-27 04:43

    Thank @greg.kindel 's answer, you help me find a solution to solve anchor problem. This code let AngularJS app IGNORE some hash pattern, keep it working like browser default. I don't need enable html5Mode, and ngRoute still working. :)

    app.config(['$provide', function ($provide) {
        $provide.decorator('$browser', ['$delegate', '$window', function ($delegate, $window) {
            // normal anchors
            let ignoredPattern = /^#[a-zA-Z0-9].*/;
            let originalOnUrlChange = $delegate.onUrlChange;
            $delegate.onUrlChange = function (...args) {
                if (ignoredPattern.test($window.location.hash)) return;
                originalOnUrlChange.apply($delegate, args);
            };
            let originalUrl = $delegate.url;
            $delegate.url = function (...args) {
                if (ignoredPattern.test($window.location.hash)) return $window.location.href;
                return originalUrl.apply($delegate, args);
            };
            return $delegate;
        }]);
    }]);
    

    Tested in Chrome 69, Firefox 62

    AngularJS 1.7.4

    0 讨论(0)
  • 2020-11-27 04:52

    I use a local copy of angular.js. Search for

    $browser.onUrlChange(function(newUrl, newState) {
    

    and

    $rootScope.$watch(function $locationWatch() {
    

    comment out the corresponding lines and angularjs will stop watch for location url changes.

    0 讨论(0)
提交回复
热议问题