17

ツールチップを表示するためのディレクティブを作成しました:

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

                scope.setStyle(e);

            });
        }
    }
});

対応するsetStyle()機能:

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

    $scope.$digest();
};

$scope.styleこれに適用されます:

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

これは私のビューの一部であり、所有するコントローラーによって処理されます$scope.style

以前に宣言および初期化され$digest()た に変更を適用するために、なぜ を呼び出さなければならないのですか?$scope.style

4

3 に答える 3

26

イベントにアタッチされたコールバックmouseenterは angular の範囲外にあるためです。angular は、その関数がいつ実行/終了するかわからないため、ダイジェスト サイクルは実行されません。

angular を呼び出し$digestてバインディングを更新し、ウォッチを起動するように指示します。$apply

于 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() には 2 つの実装があります。1 つは引数を持たず、もう 1 つは関数を引数として取り、それを評価し、digest() をトリガーします。後者を使用すると、 $exceptionHandler サービスによって処理される try/catch 句で関数がラップされるため、利点があります。

ただし、次のようにすることもできます。

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

これにより、適用する関数呼び出しがラップされ、ダイジェストが自動トリガーされます。

于 2015-02-25T21:39:19.327 に答える