angular $ location,$ route生命周期事件在浏览器编码url时触发两次

时间:2014-07-27 21:14:09

标签: angularjs angularjs-routing url-parameters

使用角度1.2.10

  

更新:问题也发生在最新的遗产(1.2.21)和测试版中   版本(1.3.0-beta.17

我提供了一个简化示例,演示了我在下面遇到的问题

基本上,我看到并试图阻止的行为是当我的应用加载其网址为的路由时 由浏览器自动编码(例如,因为参数值中有空格 +'s ),我看到 $ location 和< strong> $ route 服务生命周期事件 两次被解雇 使用下面提供的示例,复制此行为的最简单方法是加载应用程序并附加以下参数:

?message=test val

?message=test+val

如果查看控制台输出,您会看到第一个示例导致 $ locationChangeStart $ locationChangeSuccess 处理程序被触发两次。 基于文档,我相信angular正在监视地址栏中的更改,我猜测它会为未编码的URL触发这些事件然后再次 一旦编码。

有没有办法防止这种情况发生?

注意:我还注意到,尽管'+'是参数值中空格的有效替代品,但结果值仍保留'+'; ie?message = test + val将呈现为'test + val'而不是'test val'。此问题已存在ticket

更新:我和角色团队打开了这个ticket

   <!DOCTYPE html>
    <html id="ng-app" data-ng-app="test">
    <head>
        <script src="angular.js"></script>
        <script src="angular-route.js"></script>
        <script>
            'use strict';
            angular.module('test', ['ngRoute'])
                .config(function($routeProvider) {
                    $routeProvider.when('/',
                            {
                                template: '{{data.params}}',
                                controller:'TestCtrl',
                                resolve:{params: function($route) {return $route.current.params;}}
                            })
                })
                .run(function($rootScope) {
                    $rootScope.$on('$locationChangeStart',function(event, next, current){
                        console.log(event.name,'current=' + current,'next=' + next);
                    });
                    $rootScope.$on('$locationChangeSuccess',function(event, next, current){
                        console.log(event.name,'current=' + current,'next=' + next,'\n');
                    });
                })
                .controller('TestCtrl',function($scope,params){
console.log('Inside TestCtrl');
$scope.data={params:params};});
        </script>
    </head>
    <body>
        <div ng-view></div>
    </body>
    </html>

1 个答案:

答案 0 :(得分:0)

我刚遇到同样的问题。在我的情况下,它是在尝试处理历史记录时,由于某种原因,第二个生命周期是清除我的片段标识符,因此部分页面刷新不起作用。

我能绕过它的唯一方法是查看 $ location.search()以查看它是否是有效的更改并调用 event.preventDefault() $ locationChangeStart 处理程序中,如果不是。这可以防止它继续执行 $ locationChangeSuccess 处理程序。在您的情况下,您可以检查 location.url()以查看该网址是否已编码?如果没有,只需终止循环并等待编码的URL触发。

我知道这是一个黑客,但它解决了我的问题。