Как правильно конвертировать контроллер и сервис из 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 ответа:
Я согласен с @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 цента по этому вопросу.