为什么我必须在这里调用$ scope.$ digest()?

use*_*960 16 data-binding angularjs angularjs-directive

我创建了一个显示工具提示的指令:

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

                scope.setStyle(e);

            });
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

相应的setStyle()功能:

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

    $scope.$digest();
};
Run Code Online (Sandbox Code Playgroud)

$scope.style 适用于此:

<span ng-style="style">I am a tooltip</span>
Run Code Online (Sandbox Code Playgroud)

这是我视图的一部分,由拥有的控制器处理 $scope.style

为什么我必须调用$digest()才能应用更改$scope.style,之前已声明并初始化?

noj*_*noj 23

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

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

  • 不,这是在角度范围之外你必须做的事情.更好的方法是在你的指令中包含`$ digest/$ apply`调用:`scope.$ apply(function(){scope.setStyle(e);});` (3认同)

pac*_*age 12

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

以下是适合您情况的更合适的代码:

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

并且setStyle():

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