5

我有两个网络服务:

一个返回“文章”是这样的:

[   
    {
        "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 的最佳方法是什么?

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;
}])

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

4

3 回答 3

6

在与 API 通信时,我会推荐以下方法来构建您的服务(如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。服务器端组合会快很多倍。

于 2013-02-21T20:33:44.603 回答
2

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

https://github.com/jsog/jsog

于 2014-02-22T17:12:32.113 回答
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

于 2013-02-21T20:18:50.720 回答