Как правильно конвертировать контроллер и сервис из AngularJS в использование ng-resource


Я только недавно начал изучать ng-ресурс. Мне интересно, нахожусь ли я на правильном пути, когда речь заходит о преобразовании моего обычного приложения AngularJS в то, которое использует ng-ресурс.

Это мой старый home.js контроллер (без использования ng-ресурса):

angular.module("HomeApp", ["BaseApp"])
    .controller("MainCtrl", ["$http", "$window", "BaseService", function($http, $window, BaseService) {

        var self = this;

        BaseService.fetch.posts(function() {
            self.posts = BaseService.posts;
            self.cerrorMessages = BaseService.cerrorMessages;
        });

        self.like = function(id, postType) {
            BaseService.like(id, postType, function() {
                self.cerrorMessages = BaseService.cerrorMessages;
            });
        };
    }]);

А это мой старый base.js (BaseService):

angular.module("BaseApp", [])
    .factory("BaseService", ["$http", "$window", function($http, $window) {
        var self = this;
        self.posts = [];
        self.cerrorMessages = [];
        self.accessErrors = function(data) {
             self.cerrorMessages = [];
             for (prop in data) {
                 if (data.hasOwnProperty(prop)){
                     self.cerrorMessages.push(data[prop]);
                 }
             }
         };

        self.fetch = {
             posts: function(callback) {
                 $http.get('/posts/')
                 .then(function(response) {
                     self.posts = response.data;
                     callback();
                 }, function(response) {
                     self.accessErrors(response.data);
                     callback();
                 });
             }
         };

        self.like = function(id, postType, callback) {
            $http.post("/" + postType + "/" + id + "/like/")
            .then(function(response) {
                angular.forEach(self.posts, function(post, index, obj) {
                    if (post.id == id) {
                        post.usersVoted.push('voted');
                        post.voted=true;
                    };
                });
            }, function(response) {
                 self.accessErrors(response.data);
                 callback();
            });
        };

        return self;
    }]);
Мне сказали, что я могу извлечь большую пользу из использования ng-ресурсов, так как у меня есть спокойный бэкэнд. Я попытался преобразовать код выше, чтобы начать использовать ng-resource, и это то, что у меня есть сейчас. Это мой resources.js:
angular.module('PostsResources', ['ngResource'])

.factory('PostsFactory', function($resource) {
  return $resource('/posts/:postId', { postId:'@id' });
});

.factory('PostLikeFactory', function($resource) {
  return $resource('/posts/:postId/like', { postId:'@id' });
});

А это мой контроллер (home.js):

angular.module("HomePageApp", ["BaseApp", "PostsApp"])
    .controller("MainCtrl", ["$http", "$window", "BaseService", "PostsResource", "PostLikeResource", function($http, $window, BaseService, PostsResource, PostLikeResource) {

var self = this;

function loadPosts() {
    self.posts = PostsFactory.query(function(data) {},
        function(error) {
          BaseService.accessErrors(error.data);
          self.cerrorMessages = BaseService.cerrorMessages;
        }
    );
};

self.like = function likePost() {
    PostLikeFactory.save(function(data) {
        angular.forEach(self.posts, function(post, index, obj) {
            if (post.id == id) {
                post.usersVoted.push('voted');
                post.voted=true;
            };
        });
    }, function(error) {
        BaseService.accessErrors(error.data);
        self.cerrorMessages = BaseService.cerrorMessages;
    }
)};

И это моя базовая служба (base.js):

angular.module("BaseApp", [])
    .factory("BaseService", ["$http", "$window", function($http, $window) {
        var self = this;
        self.posts = [];
        self.cerrorMessages = [];
        self.accessErrors = function(data) {
             self.cerrorMessages = [];
             for (prop in data) {
                 if (data.hasOwnProperty(prop)){
                     self.cerrorMessages.push(data[prop]);
                 }
             }
         };
        return self;
    }]);

На правильном ли я пути преобразования обычного приложения AngularJS в использование ng-resource? Мне кажется, что количество требуемого кода выглядит одинаково. Заранее спасибо!

2 10

2 ответа:

Я согласен с @Mark, что у вас, вероятно, недостаточно операций в вашем API, чтобы полностью использовать $resource, поэтому преимущества не так велики. Для того, что у вас есть сейчас, если вы хотите использовать $ resource, я бы настроил его следующим образом:

angular.module('PostsResources', ['ngResource'])
   .factory('Post', function($resource) {
      return $resource('/posts/:postId', { postId:'@id' }, {
         like: {
            url: '/posts/:postId/like',
            method: 'POST',
            params: { postId:'@id' }
         }
      })
   });

Если вы доберетесь до места, где вы используете более одного действия на конечную точку, у меня будет Post и PostLike ресурс, но в вашем случае это не обязательно.

В вашем контроллере вы сможете работать со своими постами, такими как это:

self.posts = Post.query(null, BaseService.errorHandler(self));

self.like = function(post) {
   post.$like(function() {
      angular.forEach(self.posts, function(post, index, obj) {
            if (post.id == id) {
                post.usersVoted.push('voted');
                post.voted=true;
            };
        });
   }, BaseService.errorHandler(self));
};

Метод errorHandler, который вы можете добавить в свой базовый сервис, чтобы избавиться от некоторого дублирования. Это выглядело бы примерно так:

self.errorHandler = function(viewModel) {
   return function(error) {
      BaseService.accessErrors(error.data);
      viewModel.cerrorMessages = BaseService.cerrorMessages;
   };
};

Как правило, я использую ng-resource только тогда, когда у меня есть полные веб-приложения CRUD. Примером может служить CRM-приложение, в котором вам нужно создавать клиентов, обновлять клиентов, удалять клиентов и показывать список клиентов. Имеет смысл использовать ng-ресурс, так как он "обрабатывает"get, post, put, и delete HTTP методы для вас.

Однако в вашем примере кажется, что единственные действия, которые у вас есть, - это "нравится" и "получение списка сообщений". Если вы только собираетесь использовать один из методы HTTP для каждого типа ресурсов, то я бы предложил просто придерживаться вашего старого способа использования BaseService.

Только мои 2 цента по этому вопросу.