17

I created a directive for showing tooltips:

app.directive('tooltip',function(){
    return{
        restrict: 'A',
        link: function(scope,element,attr){
            element.bind('mouseenter',function(e){

                scope.setStyle(e);

            });
        }
    }
});

The corresponding setStyle() function:

$scope.setStyle = function(e){
    $scope.style = {
        position: 'absolute',
        // some other styles
    };

    $scope.$digest();
};

$scope.style is applied to this:

<span ng-style="style">I am a tooltip</span>

which is part of my view, handled by the controller who owns $scope.style

Why do i have to call $digest() in order to apply the changes to $scope.style, which was declared and initialized earlier?

4

3 回答 3

26

因为附加到mouseenter事件的回调超出了 Angular 的范围;角度不知道该函数何时运行/结束,因此永远不会运行摘要循环。

调用$digest$apply告诉 Angular 更新绑定并触发任何手表。

于 2013-09-13T11:45:50.627 回答
12

element.bind()表示监听特定的浏览器事件并在元素上调度此事件时执行回调。在这个事件链中没有任何地方包含 Angular - 它不知道事件发生了。因此,您必须明确告诉它该事件。但是,在大多数情况下,您应该使用$scope.$apply()not $scope.$digest(),尤其是当您不确定时。

这是更适合您的情况的代码:

app.directive('tooltip',function(){
    return{
        restrict: 'A',
        link: function(scope,element,attr){
            element.bind('mouseenter',function(e){
                scope.setStyle(e);
                scope.$apply();
            });
        }
    }
});

setStyle()

$scope.setStyle = function(e){
    $scope.style = {
        position: 'absolute',
        // some other styles
    };
};
于 2013-09-13T11:47:31.137 回答
1

$scope.apply() 有两种实现,一种没有参数,另一种将函数作为参数,对其求值并触发 digest()。使用后者具有优势,因为它将您的函数包装在由 $exceptionHandler 服务处理的 try/catch 子句中。

虽然,您也可以这样做:

$scope.$apply(scope.setStyle(e));

这将包装您的函数调用以应用并自动触发摘要。

于 2015-02-25T21:39:19.327 回答