简体   繁体   中英

The right way to call http for every route AngularJs

I really new with AngularJs and I'm trying to create multiple routes with different $http requests. My problem start when the route change and the page content show later. I figure it out in some way and i think its not the right way. Hope someone can tell me if there is a better way.

Note: AngularJs version: 1.6 | Using ui router

main.js

var asTwl = angular.module('asTwl', ['ui.router']);

asTwl.controller('generals', function($scope, $http, $timeout){

    $scope.pageLoader = false;

    $scope.getPageData = function(path, postData, obj){
        $scope.pageLoader = true; 
        $http({
            method: 'post',
            url: path,
            data: postData,
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
        })
        .then(function(response) {
            if (response.data) {
                $scope.data[obj] = JSON.parse(response.data);
                $timeout(function(){
                    $scope.pageLoader = false;
                }, 100)
             }
        })
        .catch(function(e) {
            new Error('Error: ', e);
            throw e;
        })
    }
});

asTwl.controller('homePage', function($scope, $http){   
    var postData = {
      //data...
    }
    $scope.getPageData('path', postData, 'home')
})

asTwl.controller('singlePage', function($scope, $http, $stateParams){   
    var postData = $stateParams;
    $scope.getPageData('path', postData, 'page')
})

asTwl.controller('categoryPage', function($scope, $http, $stateParams){   
    var postData = $stateParams;
    $scope.getPageData('path', postData, 'category')
})

asTwl.config(function($stateProvider, $urlRouterProvider, $locationProvider){

    $urlRouterProvider.otherwise('/');

    $stateProvider
    .state('home', {
        url: '/',
        templateUrl : 'templates/pages/home.html',
        controller : 'homePage'
    })
    .state('info', {
        url: '/info/:id',
        templateUrl : 'templates/pages/info.html',
        controller : 'singlePage'
    })
    .state('category', {
        url: '/category/:type/:id',
        templateUrl : 'templates/pages/category.html',
        controller : 'categoryPage'
    })
});

Thank you!

First, wrap your $http calls to services. Next,try to use resolve https://github.com/angular-ui/ui-router/wiki#resolve

Edit

Ok, example is here (without wrapping to service):

$stateProvider
.state('home', {
    url: '/',
    templateUrl : 'templates/pages/home.html',
    controller : 'homePage',
    resolve: {
       routeData:  function($http){
        return $http({
        method: 'post',
        url: 'path',
        data: postData /* your POST data - i don't know what is it for your code*/,
        headers: { 'Content-Type': 'application/x-www-form-urlencoded'               }
        })
     }
    }
})
.state('info', {
    url: '/info/:id',
    templateUrl : 'templates/pages/info.html',
    controller : 'singlePage'
})
.state('category', {
    url: '/category/:type/:id',
    templateUrl : 'templates/pages/category.html',
    controller : 'categoryPage'
})

And in controller:

asTwl.controller('homePage', function($scope, routeData){   
      $scope.someData = routeData;
})

You should first create a service which will be responsible for communicating with Server/API for playing around with data. You could include that method getPageData in that, it returns a promise object.

Service

app.service('myService', function($http){
   var self = this;
   self.getPageData = function(path, postData){
        return $http.post(path,postData, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' });
        .catch(function(e) {
            new Error('Error: ', e);
            throw e;
    });
});

Then you could easily utilize the resolve option of state of ui-router will wait till your ajax promise gets resolved.

.state('info', {
    url: '/info/:id',
    templateUrl : 'templates/pages/info.html',
    controller : 'singlePage',
    resolve: {
       getData: function(myService) {
          return myService.getPageData('path', {}, 'info')
       }
    }
})

In a nutshell your routes have to be changed like this:

.state('category', {
    resolve: {
       data : ($stateParams, dataService) => dataService.getData('path', $stateParams, 'category')
    },
    url: '/category/:type/:id',
    templateUrl : 'templates/pages/category.html',
    controller : 'categoryPage'
})

And getData method should be refactored to the service ( dataService )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM