Используя руководство по стилю John Papa AngularJS, как правильно объявлять объекты данных?
Скажем, что у меня есть служба данных AngularJS, которая делает вызов на сервер и возвращает объект, который может быть расширен с помощью дополнительных методов. Например, предположим, что следующая функция является частью службы AngularJS для чего-то вроде NerdDinner.
function getDinner(dinnerId) {
return $http.get('api/dinner/' + dinnerId)
.then(loadDinnerComplete)
.catch(loadDinnerFailed);
function loadDinnerComplete(response) {
return new Dinner(response.data);
}
}
Какая лучшая практика для места, чтобы определить класс Ужин? Это factory в отдельном файле? Определить ли это в службе NerdDinner? Или я определяю это в классе GetDinner (предполагая, что единственный метод, который может создавать обеды)?
Я не нашел никакой конкретной ссылки на создание объектов в руководство по стилю, поэтому простите меня, если оно будет закрыто, и я просто пропустил его.
Edit
Я в конечном итоге решил принять Jeroen answer, потому что он наиболее соответствовал моим потребностям в довольно простом случае использования. Тем не менее, Даниэль отвечает, является чистым золотом, и его не следует упускать из виду. Если бы я решил расширить функциональность моего DTO с помощью простых CRUD или дополнительных операций на сервере, ресурс $- отличный подход.
Ответы
Ответ 1
Где разместить бизнес-единицы (например, ужин) не упоминается в руководстве по стилю Джона Папа (afaik).
Если вы хотите пройти этот маршрут (используя бизнес-сущности и логику размещения там), я должен предоставить каждой организации свой собственный factory:
(function() {
'use strict';
angular
.module('myDinner')
.factory('Dinner', DinnerFactory);
function DinnerFactory() {
Dinner.prototype.eat = eat;
Dinner.prototype.cancel = cancel;
return Dinner;
// Constructor
function Dinner (data) {
// this is just an example:
this.time = data.time;
this.location = data.location;
}
// Methods
function eat() {
// ...
}
function cancel() {
// ...
}
}
})();
Затем вы можете ввести их в свой контроллер или, возможно, другие объекты службы, просто используя Dinner
и создать новый объект Dinner
, используя new Dinner(data)
.
Вы также можете воспользоваться услугой, но Джон Папа отмахивается от услуг, потому что они слишком похожи на фабрики.
Ответ 2
ИМО, что вы делаете, уже сделано в $resource
и restacular. Вы говорите об "определении объектов данных" (или моделей в типичном языке). Тем не менее, определение каждого "объекта данных", поскольку его собственный factory - это способ сделать это, согласно совету Джона Папа относительно одиночных проблем.
Джон Папа рассказывает об этом в разделе .
Если вы хотите это сделать вручную, IMO вы можете определить свои модели и добавить методы для каждого из них, которые будут представлять собой различные операции crud. Это шаблон $resource
и рестанглярный (вид).
//Dinner model as angular factory, each of these methods returns a promise
function Dinner($http) {
return {
create: function(route, body) { /** http.post */ },
get: function(route) { /** http.get */ },
update: function(route, body) { /** http.put */ },
destroy: function(route) { /** http.delete */ }
};
}
теперь ваша модель Dinner
имеет удобные методы crud, встроенные, чтобы вы могли сделать
var dinner = new Dinner;
dinner.get("/api/dinner/1").then() //get dinner with id of 1
dinner.update("/api/dinner/1", {name: "burger"}).then() //update dinner with id of 1
Edit:
Итак, если вы хотите создать объект, который не связан с получением данных, IMO вы должны создать еще один factory, который требует вашей модели. Это отделяет ваши данные от манипуляций с данными. В оригинальном примере OPs поиск и обработка данных тесно связаны.
function Meal(dinner) {
//this.meal is the specified dinner
this.meal = new Dinner().get("/api/dinner" + dinner);
//some random build-in data manipulation methods
return {
getCalories: function() { return this.meal * 400; },
getPrice: function() { return (this.meal * 100) + "$"; }
};
}
Теперь, когда вы разделили свои манипуляции с данными на отдельный объект, вы можете сделать что-то вроде этого (это, однако, синхронный пример)
var mcdonalds = new Meal(/** specify which dinner */)
mcdonalds.getPrice() //$4.56
mcdonalds.getCalores() //9999
Ответ 3
Лично я использовал Services
и Factories
для создания объектов. Однако из руководства по стилю Джона Папа:
Службы создаются с помощью ключевого слова new
, используйте this
для общедоступных методов и переменных. Так как они настолько похожи на фабрики, используйте factory вместо этого для согласованности.
Следуя SRP, вы должны поместить его в новый Service
или Factory
не часть другого.