angular.jsをやってみる (14) - $scope.$apply -
参考: AngularJS のデータバインドを支える $apply
公式リファレンス: http://docs.angularjs.org/api/ng/type/$rootScope.Scope
angular.jsにある$httpを使ってXHRするようなケースパターンだと$applyは内部的に行われているらしいので必要ないらしいのですが、$httpを使わずに独自でXHRを使ってHTTPリクエストを行いレスポンスを取得して結果をビューにバインドしたいようなケースの場合には$applyをしないとデータバインドが正常に行われない模様。というか行われないではなくてされてはいるけど、それが反映されない状態になってるだけなのかなと
という事でやってみた。ちょっと前に書いてたTwitter APIを使ったChrome拡張なやつでangular.jsを使ってはいるが$httpを使ってないケースなのでこれがちょうど良いのではと
angular.module("twitterApp", [])
.controller("twitter", function($scope) {
chrome.runtime.getBackgroundPage(function(bg) {
var twitter = bg.twitter;
$scope.navHome = function() {
twitter.home_timeline(function(tweets) {
$scope.tweets = tweets;
});
};
$scope.navHome();
});
});
っていう感じなコントローラーでnavHomeな所でホームタイムラインを取得してバインドするような形になっているけど、これデータバインドは正常に行われない。まぁ$scope.$applyをすれば良いんですが
twitter.home_timeline(function(tweets) {
$scope.$apply(function() {
$scope.tweets = tweets;
});
});
っていう感じにすれば良い。で$scope.$applyって何をしているのかというと
- $apply(m) なmを$scope.evalする
- finallyで$scope.$digestする
っていう所っぽい。なので
twitter.home_timeline(function(tweets) {
$scope.tweets = tweets;
$scope.$digest();
});
っていう感じで$applyしなくても最後に(そこはfinallyなりで)$scope.$digestを呼べば良い模様
んまぁ実際になぜデータバインドが正常に行われないのが原因が不透明で微妙だったがこの参考記事を見て分かったような気がする