使用工厂

时间:2015-05-28 13:19:36

标签: javascript angularjs rest

我已经编写了一个后端服务,该服务由Angular.JS前端使用工厂使用,如下所示:

angular.module('app.social', ['ngResource'])
    .factory('Social', function($http) {
        return {
            me: function() {
                return $http.get('http://localhost:3000/me');
            },
            likeVideo: function(link) {
                return $http.post('http://localhost:3000/like/video', { link : link });
            },
            post: function(link) {
                return $http.post('http://localhost:3000/post', { link : link });
            },
            postVideo: function(link) {
                return $http.post('http://localhost:3000/post/video', { link : link });
            },
            friends: function() {
                return $http.get('http://localhost:3000/friends');
            },
            taggableFriends: function() {
                return $http.get('http://localhost:3000/friends/taggable');
            },
            videos: function() {
                return $http.get('http://localhost:3000/videos');
            }
        };
    });

Social.me端点从REST后端接收配置文件信息。但是,此功能用于各种角度控制器(配置文件页面,项目详细信息页面,标题帐户按钮等)。这意味着对于每个视图,都会从http://localhost:3000/me请求配置文件信息。这是一个好的做法,还是在工厂内缓存信息更好?

编辑:更新的代码(基于@Rebornix的答案):

angular.module('app.social', ['ngResource'])
    .service('SocialService', function() {
        var serviceData = {
            me: null
        };
        return serviceData;
    })
    .factory('Social', function($http, SocialService) {
        return {
            me: function() {
                if (SocialService.me === null) {
                    return $http.get('http://localhost:3000/me').then(function(response) {
                        SocialService.me = response.data;
                        return SocialService.me;
                    });
                } else {
                    return SocialService.me;
                }
            }
        }
    };
});

在控制器中,我使用:

angular.module('app.profile', [])
    .controller('ProfileCtrl', ['$window', '$scope', 'Social', function($window, $scope, Social) {
        $scope.me = Social.me();
    }])

观点:

<div ng-controller="ProfileCtrl">
    <h1 class="profile-name">{{ me.name }}</h1>
</div>

但是视图没有更新,因为Facebook.me值在第一次请求时被初始化。我想我必须手动触发$ scope。$ apply()不知何故?

2 个答案:

答案 0 :(得分:4)

您可以通过控制器(如

)创建服务作为存储
angular.module('app.social', ['ngResource'])
.service("SocialService", function() {
   var info = {
     me: null,
     friends: []
   };
   return info;
})
.factory('Social', function($http, SocialService) {
    return {
        me: function() {
               $http.get('http://localhost:3000/me').then(function(response){
               SocialService.me = response.data;
               });
        },

然后在所有控制器中,引用infoService而不是再次调用API。您需要获取最新数据并刷新infoService,所有控制器范围都将通知此更改。

在您的控制器中

angular.module('app.profile', [])
    .controller('ProfileCtrl', ['$window', '$scope', 'SocialService', 'Social', function($window, $scope, SocialService, Social) {
    $scope.SocialService = SocialService;
    // Kick off social factory to update user info, you can move it into 
    // any other functions like `ng-click`.
    Social.me();
}])

然后在你看来

{{SocialService.me}}

答案 1 :(得分:0)

(function (app) {
'use strict';

app.factory('myService', MyService);

MyService.$inject = ['$q', 'serviceResource'];

function MyService($q, serviceResource) {
    var jobs = [];

    var service = {
        getJobs: getJobs
    };

    return service;

    //////////////////////////////////////

    function getJobs(refresh) {
        if (refresh) {
            return serviceResource.autosysJobs().$promise.then(function (data) {
                    jobs = data;
                    return jobs;
                }, function (err) {
                    throw err;
                });
        }
        else {
            var deferrer = $q.defer();
            deferrer.resolve(jobs);
            return deferrer.promise;
        }
    }
}
}(angular.module('app')));

您可以通过bool参数告诉天气获取本地副本或新副本

这完全取决于后端数据更改中数据更改的频率以及应用程序中数据不一致的容忍程度。如果源数据变化太频繁并且您无法提供不一致的数据,那么除了每次都获得新的副本之外别无选择,但如果情况并非如此,那么您可以在本地兑现数据