【问题标题】:Blocking $http in an AngularJS Service?在 AngularJS 服务中阻止 $http?
【发布时间】:2014-01-02 17:04:04
【问题描述】:

假设我有一个站点,其中每个控制器都将依赖一个“用户”对象。所以我为控制器创建了一个用户服务来获取这些数据:

myApp.factory('UserService', function ($http) {
    var user = { Id: 1, Name: 'Test' }; 
    return {
        User: user
    };
});

我的控制器看起来像这样:

myApp.controller('SearchController', function ($scope, UserService) {
    $scope.User = UserService.User;
})

我的问题是,假设现在我们需要从 $http 调用中提取该数据(然后在将返回的数据移交给控制器之前对其进行操作)并且几乎每个控制器都将需要这些数据(所以让他们每个人都操纵它没有意义),我该如何实现呢?

我正在讨论有关承诺的示例,因此我对处理此问题的正确方法感到困惑。理想情况下,我只需要一种方法来在填充任何控制器/视图之前解析这些数据

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    我会避免让服务做这样的事情,因为让服务保持状态通常是不好的形式(这是有争议的Should an Angular service have state?

    我在最近的应用程序中解决了这个问题,方法是在 rootscope 上创建一个获取用户的函数,并在我需要了解用户时调用该函数。

    【讨论】:

    • 那个方法是什么样的?它也只是回报承诺吗?
    【解决方案2】:

    我的主要挂断是收到数据后的处理,我可以通过像这样包装$http 承诺来处理:

    myApp.factory('UserService', function ($http, $q) {
        var dfrd = $q.defer();
    
        $http({ method: 'GET', url: '/api/User' }).success(function (data, status, headers, config) {
            dfrd.resolve({
                Name: data.UserName,
                /*More custom properties */
            });
        });
    
        return {
            getUser: function () { return dfrd.promise; }
        };
    });
    
    myApp.controller('SearchController', function ($scope, $location, UserService) {
        UserService.getUser().then(function (data) {
            $scope.User = data;
        });
    }
    

    【讨论】:

    • 你不应该这样做。相反,您应该使用解析器模式。 ui-router 内置了它。基本上,它是这样工作的。您创建一个解析器来解析您需要的所有承诺,并且它不会实例化控制器,直到您需要解决的每一个承诺都得到解决。然后解析器服务被注入到您的控制器中,它不是对承诺的引用,而是对您完全解析的对象的引用。查看 John Papa johnpapa.net/route-resolve-and-controller-activate-in-angularjs 的这篇精彩文章 它使测试变得更容易
    猜你喜欢
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-20
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    相关资源
    最近更新 更多