1

我只是在玩 angular 和它的 DI。我也尝试使用 Promise 范式,但是在 Chrome 扩展程序中使用它时遇到了一个相当奇怪的问题。

以下代码运行良好。当调用“chromeStorageService”中的对象字面量中的 cb() 时,promise 就解决了。但是当我取消注释返回时chrome.storage.local;,代码停止工作。我不明白为什么,因为console.log('going to be resolved');仍然被解雇,但成功警报却没有。提前感谢任何提示:)

http://jsfiddle.net/Ku5dz/

https://developer.chrome.com/extensions/storage.html

'use strict';
var app = {};

app = angular.module('options', ['options.controllers']);

app.services = angular.module('options.services', []);


app.services.factory('chromeStorageService', function () {
    //return chrome.storage.local;


    return {
        get: function(id, cb) {
            cb();
        }
    }
});

app.services.factory('storageService', ['chromeStorageService', '$q', function (chromeStorage, $q) {
    return new function () {
        this.get = function (identifier) {
            var defered = $q.defer();

            chromeStorage.get(identifier, function (items) {
                var error = false//chrome.runtime.lastError;
                if (error) {
                    return defered.reject(error);
                }

                console.log('going to be resolved');
                console.log(defered);
                defered.resolve();
            });

            return defered.promise;
        }
    }
}]);

app.services.factory('fooService', ['storageService', function (testService) {
    return new function () {
        this.getAll = function () {
            var promise = testService.get('foo');
            console.log(promise);
            promise.then(
                function () {
                    alert('success');
                }, function () {
                    aler('err');
                }
            );
        }
    }
}]);


app.directive('foo', ['fooService', function (fooService) {
    return {
        restrict:'A',
        link:function (scope, elm, attrs, ctrl) {
            fooService.getAll();    
        }
    };
}]);


app.controllers = angular.module('options.controllers', ['options.services']);
4

4 回答 4

6

Angular 有自己的小事件循环。当你.resolve做出承诺时,它就会进入 Angular 的队列。只有当 Angular 清除它的队列时,事情才会发生。

通常的做法是:

$scope.$apply(function() {
  promise.resolve(thing);
});

当控制权从您传递给它的函数返回到 $apply 时,它会清除队列,一切都很美好。在这种情况下,您可能需要将 $rootScope 注入服务中,以便您可以应用某些内容,因为视图未在 AngularJS 中更新

您的存根可以工作,因为存根永远不会离开角度世界,因此您已经处于处理队列的上下文中。当您使用 chrome.storage.local 时,不会从这样的上下文中调用您的回调。

于 2013-05-04T03:35:43.693 回答
1

我今天遇到了同样的问题。我想将chrome.storage.local.get与 Angular 承诺模式集成,原因chrome.storage.local.get是异步函数。我就是这样做的:

// service
angular.module('app').factory('STORAGE', function($q) {
    return {
        get: function(key) {
            var deferred = $q.defer();

            chrome.storage.local.get(key, function(data) {
                deferred.resolve(data[key]);
            });

            return deferred.promise;
        },
        set: function(key, value) {
            var deferred = $q.defer();

            var data = {};
            data[key] = value;
            chrome.storage.local.set(data, function() {
                deferred.resolve({});
            });

            return deferred.promise;
        },
        del: function(key) {
            var deferred = $q.defer();

            chrome.storage.local.remove(key, function() {
                deferred.resolve({});
            });

            return deferred.promise;
        }
    }
});

STORAGE我定义了一个可以封装 chrome.storage.local的 Angular 服务调用。get,setdel方法。

然后我们可以注入STORAGE到 Angular 路由resolve部分

// route resolve
...
resolve: {
    hasToken: function(STORAGE) {
        return (STORAGE.get('instagram_access_token')) ? true : false;
    }
}
...

注入路由解析参数和STORAGE控制器

// controller 
angular.module('app').controller('HomeController', ['$scope', 'hasToken', 'STORAGE',
    function($scope, hasToken, STORAGE) {
        $scope.hasToken = hasToken;

        if ($scope.hasToken) {
            STORAGE.get('profile').then(function(data) {
                $scope.user = data;
            });
        }
    }
]);

它运作良好。

于 2014-07-24T12:03:16.980 回答
0

基本上,您的代码未运行的原因是因为您正在返回 chrome.local.storage ,这会将您带出范围,并且 get 函数永远没有机会执行。请参阅 chrome API 如何做到这一点,它将与 angular 的 $http 服务非常相似

于 2013-01-29T21:49:55.063 回答
-2

如果您在 get 之前取消注释 return ,除了 get 调用之外,您如何?

基本上,只要您返回“某物”,您就会失去功能

在 Angular js 中,您可以使用以下语法调用 then 函数

    $http.get(url).then(function(response){
           //put your callback code here
       }) 
于 2013-01-29T21:33:21.970 回答