如何在处理非角度代码时立即更新$ scope?

时间:2015-02-22 23:15:38

标签: javascript angularjs angularjs-scope

我必须处理非角度库,需要在它们之间创建一个通信。

<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);

如何立即更新模型?

3 个答案:

答案 0 :(得分:2)

我尝试使用$scope.$evalAsync作为@Kjell建议,但没有用。

在阅读了更多关于$ scope之后,我找到了我需要的东西。

$scope.$applyAsync(function(){
    var settings = {} 
    LibraryCall(settings);
});

$scope.$applyAsync将安排$ apply的调用在以后发生。

https://docs.angularjs.org/api/ng/type/ $ rootScope.Scope

答案 1 :(得分:1)

为简洁起见,我删除了错误回调,请勿在代码中执行此操作:)

我认为你调用的代码是异步的,如果不是,你不应该有任何$ scope更新问题(因为所有有角度的promise都已经调用$ 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确实已经在$ apply调用上包装了promise回调。

$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';
        });
    });
})

答案 2 :(得分:0)

尝试使用$ scope。$ evalAsync()或$ scope。$ applyAsync()。 它们是为这样的东西制作的。它将在以后执行代码。与$ timeout没有什么不同,但可能更快。

$scope.$evalAsync(function(){
    var settings = {} 
    LibraryCall(settings);
})

编辑:仅仅引用Ben Nadel关于来自this post的$ timeout和$ evalAsync之间的区别:

  

所以,实质上,$ scope。$ evalAsync()结合了两者的优点:   如果可以(大部分时间),它将评估你的   在同一个刻度中表达;否则,它会评估你的   在后面的tick中表达式,这正是$ timeout()正在做的事情。