以正确的方式管理AngularJS中的数据模型

时间:2014-08-28 00:14:29

标签: angularjs

当我浏览互联网时,我发现有很多不同的方法来管理我们的Angular模板中使用的数据模型,但它们只显示了大局的一小部分。在大型应用程序中,我们需要将API数据粘合到某种形式的JavaScript模型中,而这种模型又在我们的模板中使用,但我不确定如何管理它们。

阅读this article on AngularJS models后,我现在意识到我应该将所有模型包装在服务中,以便跨多个控制器提供信息。其中一个原因是它没有解释如何将这些服务与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 Service中,因此可以跨多个控制器使用。这个新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对象。

我想知道你对这种困境的初步反应?

更新

我遇到了this article,它将模型的所有功能(包括API请求)整合到工厂服务中

1 个答案:

答案 0 :(得分:7)

模型服务和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方法本身返回已解析的promise以返回then回调语句的值,因此这应该有效。 尝试这种方法并分享您的发现