カテゴリー別アーカイブ: スコープ

AngularJS 外部モジュールによるビューの更新

AngularJSでは, 双方向データバインディングによって, モデルを更新すれば即時にビューも更新されます

ところが, AngularJSが管理していない外部モジュールのイベントでモデルを更新しても即時にビューが更新されません. 更新されるのは次にAngularJSが管理しているモジュールでモデルを更新した場合です.

$scope.value = 0;

//jQuery UI Slider
$('#slider').sider({
    slide : function(event, ui) {
        //Update Model -> Not Update View ...
       $scope.value = ui.value;
    }
});

このままでは, jQuery UIやjQuery プラグインなどサードパーティ製モジュールが使いづらくなってしまいます.

しかしAngularJSにはこれを解決する手段が2つ定義されています.

  • $scope.$applyメソッドを利用する
  • $timeoutサービスを利用する
$scope.value = 0;

//jQuery UI Slider
$('#slider').sider({
    slide : function(event, ui) {
        $scope.$apply(function() {
            //Update Model -> Update View
            $scope.value = ui.value;
        });
    }
});
$scope.value = 0;

//jQuery UI Slider
$('#slider').sider({
    slide : function(event, ui) {
        $timeout(function() {
            //Update Model -> Update View
            $scope.value = ui.value;
        }, 0);
    }
});

$timeouサービスも内部的には$scope.$applyを利用しているので, 根本的にはどちらの方法も同じです.

しかし, $scope.$applyでは, 別のイベントによって更新処理が実行されているときに$scope.$applyメソッド呼び出しがあり, 更新処理が多重実行されてしまうと,

Error : {$rootScope:inprog] $digest already in progress

というエラーが出てしまいます.

$timeoutサービスではタイムアウト時間を0ミリ秒に設定することで, 更新処理の多重実行を回避して$scope.$applyを実行します.