如何在处理非 angular 代码时立即更新 $scope?
How to update $scope immediately when dealing with non angular code?
我必须处理非 angular 库并且需要在它们之间创建通信。
<div id="MoipWidget" data-token="{{personaltoken}}" callback-method-success="successCB" callback-method-error="errorCB"></div>
每次加载页面时,我都必须从服务器获取令牌。
$http.post('https://example.org', obj)
.success(function(data){
$scope.personaltoken = data.token;
//Here I call the non angular library and I get and error telling me that the token is undefined.
//If I run the code from inside a $timeout works as I need...
})
.error(function(data){
alert('error');
});
我也尝试在 $scope.$apply 中 运行 但我收到一个错误提示 $digest already in progress
我要调用的非angularjs库很简单就两行
var settings = {}
LibraryCall(settings);
如何立即更新模型?
为简洁起见,我删除了错误回调,请勿在您的代码中这样做:)
我想你调用的代码是异步的,如果不是,你不应该有任何 $scope 更新问题(因为所有 angular promises 已经调用 $apply)...
这应该有效:
$http.post('https://example.org', obj).success(function(data){
$scope.personaltoken = data.token;
otherLibrary.doSomething(data.token, function(error, result) {
$scope.changeSomething = 'toHey';
$scope.$apply();
});
});
这也应该有效:
$http.post('https://example.org', obj).success(function(data){
$scope.personaltoken = data.token;
otherLibrary.doSomething(data.token, function(error, result) {
$scope.$apply(function() {
$scope.changeSomething = 'toHey';
});
});
})
这应该引发 $digest already in progress
错误,因为 $http 确实已经将 promise 回调包装在 $apply 调用上。
$http.post('https://example.org', obj).success(function(data){
$scope.personaltoken = data.token;
$scope.$apply(function() {
otherLibrary.doSomething(data.token, function(error, result) {
$scope.changeSomething = 'toHey';
});
});
})
尝试使用 $scope.$evalAsync() 或 $scope.$applyAsync()。
它们是为这样的东西而制作的。它将稍后及时执行代码。与 $timeout 没有太大区别,但可能更快。
$scope.$evalAsync(function(){
var settings = {}
LibraryCall(settings);
})
编辑:引用 Ben Nadel 关于 $timeout 和 $evalAsync 之间的区别,来自 this post:
So, in essence, $scope.$evalAsync() combines the best of both worlds:
When it can (which is most of the time), it will evaluate your
expression in the same tick; otherwise, it will evaluate your
expression in a later tick, which is exactly what $timeout() is doing.
我尝试按照@Kjell 的建议使用$scope.$evalAsync
,但没有用。
阅读了有关 $scope 的更多信息后,我找到了我需要的东西。
$scope.$applyAsync(function(){
var settings = {}
LibraryCall(settings);
});
$scope.$applyAsync
将安排稍后调用 $apply。
https://docs.angularjs.org/api/ng/type/$rootScope.Scope
我必须处理非 angular 库并且需要在它们之间创建通信。
<div id="MoipWidget" data-token="{{personaltoken}}" callback-method-success="successCB" callback-method-error="errorCB"></div>
每次加载页面时,我都必须从服务器获取令牌。
$http.post('https://example.org', obj)
.success(function(data){
$scope.personaltoken = data.token;
//Here I call the non angular library and I get and error telling me that the token is undefined.
//If I run the code from inside a $timeout works as I need...
})
.error(function(data){
alert('error');
});
我也尝试在 $scope.$apply 中 运行 但我收到一个错误提示 $digest already in progress
我要调用的非angularjs库很简单就两行
var settings = {}
LibraryCall(settings);
如何立即更新模型?
为简洁起见,我删除了错误回调,请勿在您的代码中这样做:)
我想你调用的代码是异步的,如果不是,你不应该有任何 $scope 更新问题(因为所有 angular promises 已经调用 $apply)...
这应该有效:
$http.post('https://example.org', obj).success(function(data){
$scope.personaltoken = data.token;
otherLibrary.doSomething(data.token, function(error, result) {
$scope.changeSomething = 'toHey';
$scope.$apply();
});
});
这也应该有效:
$http.post('https://example.org', obj).success(function(data){
$scope.personaltoken = data.token;
otherLibrary.doSomething(data.token, function(error, result) {
$scope.$apply(function() {
$scope.changeSomething = 'toHey';
});
});
})
这应该引发 $digest already in progress
错误,因为 $http 确实已经将 promise 回调包装在 $apply 调用上。
$http.post('https://example.org', obj).success(function(data){
$scope.personaltoken = data.token;
$scope.$apply(function() {
otherLibrary.doSomething(data.token, function(error, result) {
$scope.changeSomething = 'toHey';
});
});
})
尝试使用 $scope.$evalAsync() 或 $scope.$applyAsync()。 它们是为这样的东西而制作的。它将稍后及时执行代码。与 $timeout 没有太大区别,但可能更快。
$scope.$evalAsync(function(){
var settings = {}
LibraryCall(settings);
})
编辑:引用 Ben Nadel 关于 $timeout 和 $evalAsync 之间的区别,来自 this post:
So, in essence, $scope.$evalAsync() combines the best of both worlds: When it can (which is most of the time), it will evaluate your expression in the same tick; otherwise, it will evaluate your expression in a later tick, which is exactly what $timeout() is doing.
我尝试按照@Kjell 的建议使用$scope.$evalAsync
,但没有用。
阅读了有关 $scope 的更多信息后,我找到了我需要的东西。
$scope.$applyAsync(function(){
var settings = {}
LibraryCall(settings);
});
$scope.$applyAsync
将安排稍后调用 $apply。
https://docs.angularjs.org/api/ng/type/$rootScope.Scope