作为AngularJS的新手,我试图了解如何管理来自单个JSON请求的单个$http.get,该请求将由2个不同的ui-view中的2个不同的控制器使用。

想法是在第一个ui-view中显示用户的数据,而在第二个中显示故事的数据。

现在,由于两个控制器两次调用两次,因此我的工厂执行了2个$http请求。

现在我所拥有的是:

homeFactory.js

var homeFactory = angular.module('home.factory', []);

homeFactory.factory('homeData', [ '$http', '$q', function ($http, $q) {

  var endpoints = null;

  return {
    getStories: function(url) {
      return endpoints ?
      $q(function(resolve, reject) { resolve(endpoints); }) :
      $http.get(url + '/main/get', {
          transformRequest : angular.identity,
          headers : {'Content-Type' : undefined}
      }).then(function(data) { endpoints = data; return data; });
    }
  };
}]);


home.js

var home = angular.module('home', ['home.factory']);

home.controller('topbarCtrl', [ 'CONFIG', 'homeData', function(CONFIG, homeData) {
  var data = this;
  data.stories = {};

  homeData.getStories(CONFIG.API_URL).then(function(response) {
    data.stories = response.data.stories;
  }, function(error) {
    console.log("Failed to load end-points list");
  });
}]);

home.controller('contentCtrl', [ 'CONFIG', 'homeData', function(CONFIG, homeData) {

  var data = this;
  data.stories = {};

  homeData.getStories(CONFIG.API_URL).then(function(response) {
    data.stories = response.data.stories;
  }, function(error) {
    console.log("Failed to load end-points list");
  });
}]);


app.js

(function () {
   var app = angular.module('init', [
      'home', 'ui.router'
   ]);

   app.run([
      '$rootScope',
      '$state',
      '$stateParams',
      function ($rootScope, $state, $stateParams) {
         $rootScope.$state = $state;
         $rootScope.$stateParams = $stateParams;
      }
   ]);

   app.constant('CONFIG', {
      'API_URL': 'https://xxxxxxxxx/',
      'S3_PATH': 'http://resources.xxxxxxxxx.com',
      'CLOUDFRONT': 'http://resources.xxxxxxxxx.com'
   });

   app.config([
      '$stateProvider',
      '$urlRouterProvider',
      '$locationProvider',
      '$sceDelegateProvider',
      function ($stateProvider, $urlRouterProvider, $locationProvider, $sceDelegateProvider) {
         $sceDelegateProvider.resourceUrlWhitelist([
            'self',
            'http://resources.xxxxxxxxx.com/**'
         ]);

         $urlRouterProvider
            .when('/logout', '/')
            .otherwise('login');

         $stateProvider
            .state('home', {
               url: "/home",
               views: {
                  'header': { templateUrl: "app/Home/_topbar.html" },
                  'content': { templateUrl: "app/Home/_home.html" },
                  'footer': { templateUrl: "app/Home/_navbar.html" }
             }
          });
       }
    ]);
 }());


index.html

<!DOCTYPE html>

<html lang="en" ng-app='init'>

<head>
  <meta charset="utf-8">
  <script src="js/angular.min.js"></script>
  <script src="js/angular-ui-router.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script>
  <script src="app/app.js"></script>
</head>
<body>
  <script src="app/Home/home.js"></script>
  <script src="app/Home/HomeFactory.js"></script>
  <div ui-view="main">
    <div ui-view="header"></div>
    <div class="wrapper" ui-view="content"></div>
    <nav ui-view="footer"></nav>
  </div>
  <script src="js/sha512.js"></script>
</body>
</html>


我怎样才能实现我所需要的?

感谢您的建议。

更新

我在主控制器上应用的解决方案是通过resolve指令请求数据,并将控制器分配给每个视图,如下所示:

$stateProvider
  .state('home', {
    url: "/home",
    resolve: {
      response: [ 'CONFIG', '$http', function(CONFIG, $http) {
        return $http.get(CONFIG.API_URL + '/home').then(function(response) {
          return response.data;
        });
      }]
    },
    views: {
      'header': { templateUrl: "app/Home/_topbar.html", controller: 'headerCtrl', controllerAs: 'my' },
      'content': { templateUrl: "app/Home/_home.html", controller: 'contentCtrl', controllerAs: 'my' },
      'footer': { templateUrl: "app/Home/_navbar.html", controller: 'footerCtrl', controllerAs: 'my' }
    }
  });


然后,您无需在html视图中声明ng-controller

最佳答案

您可以使用ui-router的resolve进行api调用并将已解析的数据注入到控制器中。

app.js

$stateProvider
     .state('home', {
         url: "/home",
         resolve: {
             response: ['homeData', '$q', 'CONFIG', function(homeData, $q, CONFIG) {
                 var deferredData = $q.defer();
                 homeData.getStories(CONFIG.API_URL).then(function(response) {
                     return deferredData.resolve({
                         data: response.data
                     });
                 })
                 return deferredData.promise;
             }]
         }
         views: {
              'header': { templateUrl: "app/Home/_topbar.html" },
              'content': { templateUrl: "app/Home/_home.html" },
              'footer': { templateUrl: "app/Home/_navbar.html" }
         }
});


控制器:

home.controller('topbarCtrl', ['response', function(response) {
    console.log(response.data) //this will contain the response data
}]);

home.controller('contentCtrl', ['response', function(response) {
    console.log(response.data) //this will contain the response data
}]);

07-24 09:50
查看更多