Управление моделями данных в AngularJS правильным способом

Когда я просматриваю интернет, я нахожу много разных способов управления моделью данных, которая используется в наших шаблонах Angular, но все они отображают только небольшую часть более крупного изображения. В большом приложении нам нужно склеивать данные API в какую-то форму JavaScript-модели, которая, в свою очередь, используется в нашем шаблоне, но я не уверен, как все это должно управляться.

После прочтения этой статьи о моделях AngularJS Теперь я знаю, что я должен обернуть все мои модели в службе, чтобы информация была доступна для нескольких контроллеров. Одна из единственных вещей заключается в том, что он не объясняет, как связать эти службы с запросами API.

Вот моя текущая реализация.

Модель клиента

var Customer = function (obj) {
    var self = this;

    if (!obj) {
        self.Name = null;
        self.Address = null;
        self.PrimaryEmailAddress = null;
        self.SecondaryEmailAddress = null;
        self.PhoneNumber = null;

    } else {
        self = obj;
    }

    return self;
}

Затем в моем контроллере я использую эту модель на моем $scope, например

Клиентский контроллер

app.controller('CustomerController', [function($scope, API){
    $scope.model = {};

    API.Account.getCustomer({id:'12345'}, function(data){
        $scope.model = new Customer(data);
    });

}]);

Это то, что моя служба API выглядит как

Служба API

app.factory("API", ["$resource", function ($resource) {

    var service = {};

    service.Account = $resource('/WebApi/Account/:type/:id', {},
                        {
                            getCustomer: { method: 'GET', params: { type: 'Customer' } }
                        });

    return service;

}])

Это довольно хорошо работает до сих пор, когда я понял, что есть информация API, которая собрана в родительском контроллере, который теперь необходим в дочернем контроллере

Возвращаясь к статье, приведенной выше, я теперь могу изменить свои модели, чтобы они были обернуты в службу Angular и поэтому доступны для нескольких контроллеров. Этот новый CustomerService может выглядеть так:

NEW CustomerService

app.factory('CustomerService', function() {
  var CustomerService = {};
  var customer = new Customer();

  CustomerService.getCustomer = function() { return customer; }
  CustomerService.setCustomer = function(obj) { customer = obj; }

  return CustomerService;
});

Это не совсем похоже на статью (намного проще), но в основном она содержит функции, подобные OO, для получения и установки объекта Customer.

Проблема с этим способом заключается в том, что мы до сих пор не имеем доступа к фактической конечной точке API для получения данных клиента с сервера? Должны ли мы поддерживать службу API и службы моделирования отдельно или пытаться объединить их в одну службу? Если мы это сделаем, нам также понадобится способ различать фактическое получение свежих данных с сервера и просто получение текущего объекта Customer в одноэлементном объекте.

Я хотел бы узнать ваш первоначальный ответ на это затруднительное положение?

UPDATE

Я столкнулся с этой статьей, которая объединяет все функциональные возможности модели, включая запросы API, в службу factory

Ответ 1

Сервис модели и сервис API должны быть раздельными. Служба API может зависеть от свойств модели и возвращаемых объектов модели, а не напрямую возвращать то, что исходило от api.

app.factory("API", ["$resource",'Customer','$q' function ($resource,Customer,$q) {

    var service = {};

    service.Account = function(accountId) {
         var defer=$q.defer();     
         var r=$resource('/WebApi/Account/:type/:id', {},
                        {
                            getCustomer: { method: 'GET', params: { type: 'Customer' }}
                        });
         r.getCustomer({id:'12345'}, function(data){
             defer.resolve(new Customer(data));
         })
         return defer.promise;
     }
     return service;

}]);

Таким образом вы объединили службу модели и службу API. Я предполагаю, что Customer - это модельная услуга, а не объект Customer.

Обновление: Основываясь на вашем последующем вопросе, я подумал, что может быть лучший способ, но я не пробовал. Вместо того, чтобы создавать собственное обещание каждый раз, когда мы можем использовать обещание ресурса:

service.Account = function(accountId) {
         var r=$resource('/WebApi/Account/:type/:id', {},
                        {
                            getCustomer: { method: 'GET', params: { type: 'Customer' }}
                        });
         return r.getCustomer({id:'12345'}).$promise.then(function(data) {
            return new Customer(data); 
         });
}

Так как сам метод then возвращает обещание, которое разрешено возвращать значение последующего оператора обратного вызова, это должно работать. Попробуйте этот подход и поделитесь своими результатами.