AngularJS作用域变量设置不正确

时间:2018-07-13 14:06:37

标签: javascript angularjs electron

我正在使用electron-json-storage,并且试图将AngularJS $scope变量设置为等于存储的数据。

下面是我的代码:

portal.controller('portalViewController', function($scope) {
    //$scope.url = "http://www.google.com"; //correctly sets $scope.url to google.com
    storage.get('portal_url', (err, data) => {
        console.log(data.url); //prints out data as it should
        $scope.url = data.url;
    });
});

如您所见,我拥有这项工作的每个独立组件,但是当我将它们组合在一起时,$scope.url似乎没有被设置。我已经坚持了一段时间,无法弄清楚问题出在哪里。我对AngularJS还是很陌生,所以我可能真的很简单。

感谢您提供的任何帮助!

2 个答案:

答案 0 :(得分:2)

由于storage似乎是第三方插件,因此$scope中的任何更改都不会执行摘要周期。使用$timeout强制进行摘要循环,以便在UI中呈现更改。

portal.controller('portalViewController', function($scope, $timeout) {
    storage.get('portal_url', (err, data) => {
        console.log(data.url); //prints out data as it should
        $timeout(function(){
            $scope.url = data.url;
        });
    });
});

答案 1 :(得分:0)

如果回调确实来自AngularJS执行上下文之外的第三方来源,则可以简单地使用$apply

portal.controller('portalViewController', function($scope) {
    storage.get('portal_url', (err, data) => {
        $scope.$apply(function() {
            $scope.url = data.url;
        });
    });
});

从文档中:

  

AngularJS通过提供自己的事件处理循环来修改常规JavaScript流。这将JavaScript分为经典和AngularJS执行上下文。只有在AngularJS执行上下文中应用的操作才能受益于AngularJS数据绑定,异常处理,属性监视等。您还可以使用$apply()从JavaScript进入AngularJS执行上下文。

     

请记住,在大多数地方(控制器,服务)$apply已由处理事件的指令为您调用。仅当实现自定义事件回调或使用第三方库回调时,才需要显式调用 $apply

     

     

— AngularJS Developer Guide - Integration with the browser event loop


将基于回调的API转换为基于AngularJS Promise的API

可以通过创建服务将基于回调的API集成到AngularJS框架中:

app.service("storageAPI", function($q) {
    this.get = function(url) {
        var deferred = $q.defer();
        storage.get(url, (err, data) => {
            if (err) { 
                deferred.reject(err);
            } else {
                deferred.resolve(data);
            };
        });
        return deferred.promise;
    };
});

用法:

app.controller('portalViewController', function($scope, storageAPI) {
    storageAPI.get('portal_url')
      .then(function(data) {
         $scope.url = data.url;
    }).catch(function(err) {
         console.log(err);
    });
});

此方法的优势在于,无需$apply($ q服务会自动执行此操作)即可将API集成到AngularJS框架中。此外,它还可以可靠地处理API中的错误。

有关更多信息,请参见 -AngularJS $q Service API Reference - The Deferred API