如何在具有某些ui视图的状态下管理工厂单个请求数据

时间:2016-05-14 12:50:07

标签: javascript angularjs

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

这个想法是在第一个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

1 个答案:

答案 0 :(得分:1)

您可以使用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
}]);