我正在使用Soundcloud JS SDK,将我的Soundcloud收藏到一个简单的Angular应用程序中。
在使用$scope.$apply
之前,我无法正确导入用户收藏夹。
function TopListCtrl($scope, $http, $modal) {
$scope.getData = function(sc_user) {
SC.get('/users/'+ sc_user +'/favorites', {limit: 200}, function(tracks){
$scope.$apply(function() {
if (Object.getOwnPropertyNames(tracks).length > 1) {
$scope.likes = tracks;
$scope.sortField = 'like.favoritings_count';
$scope.reverse = true;
$scope.sc_user = sc_user;
}
else {
alert("That user has 0 Soundcloud likes. So sad...")
}
}).error(function (data, status, headers, config) {
alert("Something went awry with that request. Double check that's a real Soundcloud username");
})
});
}
如果你不使用$scope。apply,它不起作用(并且说SC.get没有定义)。
我想更好地理解为什么$scope.$apply
是必要的。我问这个问题是因为当我只是使用http api时,我不需要它。
function TopListCtrl($scope, $http, $modal) {
$scope.getData = function(sc_user) {
var url = 'http://api.soundcloud.com/users/'+ sc_user +'/favorites.json?client_id=0553ef1b721e4783feda4f4fe6611d04&limit=200&linked_partitioning=1&callback=JSON_CALLBACK';
$http.jsonp(url).success(function(data) {
if (Object.keys(data.collection).length > 0) {
$scope.likes = data;
$scope.sortField = 'like.favoritings_count';
$scope.reverse = true;
$scope.sc_user = sc_user;
}
else {
alert("That user has 0 Soundcloud likes. So sad...")
}
}).error(function (data, status, headers, config) {
alert("Something went awry with that request. Double check that's a real Soundcloud username");
});
}
通常angular知道正在执行的代码因为你是提供函数回调的人但实际上是angular在调用它们。在angular调用一个函数之后,它会在稍后调用$apply来触发$digest循环。
如果你不知道$digest循环是什么,这个概念很简单。在$digest阶段,angular会对每个用$watch处理器设置的作用域变量进行脏检查,并检查它是否被修改了;如果有,angular会调用对应的$watch处理器来更新视图。
回到最初的问题——当angular知道你的代码时,它会为你触发一个$digest循环——所以没有必要显式地调用$apply。如果处理的是jquery事件,那就是另一回事了。Angular不知道可能需要一个$digest——它怎么知道呢?所以需要$apply来手动触发$摘要。
我知道你的问题已经得到了正确的答复。我想我还应该提到,使用$http向Soundcloud API发出请求并不是非常困难,所以你不需要使用$scope.$apply。以下是我的:
var request = function(method, path, params, callback) {
params.client_id = sc.soundcloud.client_id;
params.oauth_token = sc.soundcloud.access_token;
$http({
method: method,
url: sc.soundcloud.api.host + path,
params: params
})
.success(callback);
};
get: function(path, params, callback) {
request('GET', path, params, callback);
},
put: function(path, params, callback) {
request('PUT', path, params, callback);
},
post: function(path, params, callback) {
request('POST', path, params, callback);
},
delete: function(path, params, callback) {
request('DELETE', path, params, callback);
}
Pixelbits的回答和Jim Hoskins关于$scope的一篇文章。$apply帮助我更好地理解了这一点。以下是我最初问题的关键点:
那么,什么时候需要调用$apply()呢?实际上很少。AngularJS实际上在$apply中调用几乎所有的代码呼叫像ng-click、控制器初始化、$http回调等事件都封装在$scope.$apply()中。所以你不需要调用它你自己,其实你不能。在$apply内部调用$apply会抛出一个错误。如果你要在新的回合中运行代码,你确实需要使用它。和仅当该转弯不是由AngularJS中的方法创建时才使用图书馆。在这个新转弯中,您应该将代码封装在范围。应用()美元(强调我的)
我仍然不清楚,但我得到的关键点是,方法(SC.get
在我的情况下)不是AngularJS库的一部分,所以我,因此,需要使用$apply
。
(至少我认为我明白了)