为什么我需要一个作用域。设置 $location.path 时 $apply

Why do I need a scope.$apply when setting $location.path

在这个简单的例子中,我有一个指令拦截对元素的点击,然后使用 $location 服务导航到某个地方。为什么我需要将 $location.path() 调用包装在 $scope.$apply?

HTML:

<a my-href="/">Click me</a>

脚本:

angular.module('app').directive('myHref', function(){
        return {
            controller: function($scope, $location){
                $scope.navigate = function(path){
                    $scope.$apply(function(){
                        $location.path(path);
                    });
                };

            },
            link: function(scope, elem, attrs){
                elem.bind('click', function(){
                   scope.navigate(attrs.myHref);
                });
            }
        }
    });

Fiddle: http://jsfiddle.net/basslagter/4mya2uv0/

您通常不需要它,因为使用 angular $location 服务更新位置需要一个摘要周期来更新位置。在您的情况下,您需要它,因为您正在从 angular 上下文之外的手动绑定的单击事件(而不是使用 ng-click)调用范围函数(angular 不知道某些事件是否具有发生了,它已经更新了范围)。你也把它放在错误的地方,因为当你使用 scope.apply 时,它必须放在调用堆栈的顶部,即原点,否则你的范围函数在 [=17= 中调用时变得不可用] 语境。当您在控制器中手动执行摘要循环时,有时也是一件奇怪的事情。

例如:

 angular.module('app').directive('myHref', function(){
    return {
        controller: function($scope, $location){
            $scope.navigate = function(path){
               $location.path(path);
            };

        },
        link: function(scope, elem, attrs){
            elem.bind('click', function(){
               scope.navigate(attrs.myHref);
               scope.$apply(); //<-- Here
            });
        }
    }
});