AngularJS结合了Web服务响应

时间:2013-02-21 20:04:16

标签: ajax angularjs angularjs-service

我有两个网络服务:

一个回归"文章"像这样:

[   
    {
        "id": "1",
        "headline": "some text",
        "body": "some text",
        "authorId": "2"
    },
    {
        "id": "2",
        "headline": "some text",
        "body": "some text",
        "authorId": "1"
    }
]

另一个返回"作者"像这样,给出一个id:

{
    "id": "1",
    "name": "Test Name",
    "email": "test@test.com",
    "photo": "path/to/img"
}

我想将两者合并,因此我可以在文章概览列表中显示作者姓名和照片。

像这样:

[   
    {
        "id": "1",
        "headline": "some text",
        "body": "some text",
        "authorId": "2",
        "author_info": {
            "id": "2",
            "name": "Another Test Name",
            "email": "test2@test.com",
            "photo": "path/to/img"
        }
    },
    {
        "id": "2",
        "headline": "some text",
        "body": "some text",
        "authorId": "1"
        "author_info": {
            "id": "1",
            "name": "Test Name",
            "email": "test@test.com",
            "photo": "path/to/img"
        }
    }
]

我有"文章"获取文章的服务,但是使用来自类似作者的作者信息丰富返回的JSON的最佳方法是什么?#34; Authors"返回"文章"服务输出?

factory('Authors', ['$http', function($http){
    var Authors = {

        data: {},

        get: function(id){
            return $http.get('/api/authors/' + id + '.json')
                .success(function(data) {
                    Authors.data = data;
                })
                .error(function() {
                    return {};
                });
        }
    };

    return Authors;
}]).

factory('Articles', ['$http', 'Authors', function($http, Authors){
    var Articles = {

        data: {},

        query: function(){
            return $http.get('/api/articles.json')
                .success(function(result) {
                    Articles.data = result; // How to get the author info into this JSON object???
                })
                .error(function() {
                    Articles.data = [];
                });
        }
    };
    return Articles;
}])

请告诉我这是否是一个完全错误的方法。 :)

3 个答案:

答案 0 :(得分:6)

在与API通信时,我建议采用以下方法来构建您的服务(advised by Misko Hevery):

    // Author model/service
    angular.module('myApp').factory('Author', function($http) {
      var Author = function(data) {
        angular.extend(this, data);
      };

      Author.get = function(id) {
        return $http.get('/authors/' + id).then(function(response) {
          return new Author(response.data);
        });
      };

      return Author;
    });

    // Article model/service
    angular.module('myApp').factory('Article', function($http) {
      var Article = function(data) {
        angular.extend(this, data);
      };

      Article.query = function() {
        return $http.get('/articles/').then(function(response) {
          var articles = [];
          angular.forEach(response.data, function(data){
            articles.push(new Article(data));
          });
          return articles;
        });
      };

      return Article;
    });

    // Your controller
    angular.module('myApp')
      .controller('Ctrl'
        ,[
          '$scope'
          ,'Article'
          ,'Author'
          ,function($scope, Article, Author){
            Article.query()
              .then(function(articles){
                $scope.articles = articles;
                attachAuthors(articles);
              });

            function attachAuthors(articles){
              angular.forEach(articles, function(article){
                Author.get(article.authorId)
                  .then(function(author){
                    article.author = author;
                  });
              });
            }

          }
        ]
      );

但可以肯定的是,我还建议不要在单独的调用中获取所有这些数据。相反,如果可能,您应该让API返回组合的JSON。服务器端组合会快很多倍。

答案 1 :(得分:2)

查看JSOG。它非常适合做这类事情。目前有Java,Python,Javascript和Ruby的服务器实现。在客户端javascript端,您只需调用JSOG.decode(object)。我在Angular中大量使用它。

https://github.com/jsog/jsog

答案 2 :(得分:0)

一种选择是在服务器上组合所有这些数据,也许创建一个单独的json文件。这将简化客户端,只需要一个HTTP请求而不是两个。

如果你保留两种服务(这不是一个坏方法)你可以解雇一个,等待答案并解雇第二个。也许首先Articles,然后Authors

Articles.get(function (articles) {                
            $scope.articles = articles;
            //fire query for Authors
            Authors.query(function (authors) {
              $scope.authors= authors;
              //combine both articles and authors
              combineData(articles, authors);                    
           }) 
});

以下是组合数据的功能

function combineData(articles, authors){
  $.each(articles, function (i, article) {
      //find author
      var author = $.grep(authors, function(a, j){
                     return a.id == article.authorId;
                   });
      //set article's author
      article.author_info = author;
    });
}

请注意,使用此配置,您的文章甚至会在致电$scope.articles

之前呈现(通过设置Authors.query