AngularJS结合了Web服务响应

Jak*_*sen 5 ajax angularjs angularjs-service

我有两个网络服务:

一个人返回"文章",如下所示:

[   
    {
        "id": "1",
        "headline": "some text",
        "body": "some text",
        "authorId": "2"
    },
    {
        "id": "2",
        "headline": "some text",
        "body": "some text",
        "authorId": "1"
    }
]
Run Code Online (Sandbox Code Playgroud)

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

{
    "id": "1",
    "name": "Test Name",
    "email": "test@test.com",
    "photo": "path/to/img"
}
Run Code Online (Sandbox Code Playgroud)

我想将两者结合起来,这样我就可以在文章概览列表中显示作者姓名和照片.

像这样:

[   
    {
        "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"
        }
    }
]
Run Code Online (Sandbox Code Playgroud)

我有一个"文章"服务来获取文章,但是在返回"文章"服务输出之前,使用来自类似"作者"服务的作者信息来丰富返回的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;
}])
Run Code Online (Sandbox Code Playgroud)

如果这是一个完全错误的方法,请告诉我.:)

Ste*_*wie 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;
                  });
              });
            }

          }
        ]
      );
Run Code Online (Sandbox Code Playgroud)

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


Uli*_*ses 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);                    
           }) 
});
Run Code Online (Sandbox Code Playgroud)

这是组合数据的函数:

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;
    });
}
Run Code Online (Sandbox Code Playgroud)

$scope.articles请注意,使用此配置,即使在调用之前,您的文章也会呈现(通过设置)Authors.query