2016-07-19 7 views
0

これは重複しているかどうかわかりませんが、私のために働いていたものは見つけられませんでしたので、この質問を投稿しています。約束事後の角度状態の変化

私は、特定のルートにユーザーを誘導する前にデータベースから値を取得する必要があるため、表示するコンテンツを決定することができます。

$state.go(..)の直前にe.preventDefault()を移動すると正しく動作しません。問題は、デフォルトの状態を読み込み始め、httpからの応答を受け取ったときだけです。main.homeにリダイレクトします。つまり、dbリクエストが2秒かかるとしたら、main.homeにリダイレクトするまでに2秒かかります。つまり、ユーザは、想定されていないコンテンツを約2秒間見ています。

状態変更の開始時にデフォルトを防止し、状態変更の終了時にユーザーをリダイレクトする方法はありますか? また、状態変更の開始時にデフォルトを防止できれば、どのようにデフォルト状態を継続できますか?

(function(){ 
    "use strict"; 
    angular.module('app.routes').run(['$rootScope', '$state', '$http', function($rootScope, $state, $http){ 
     /* State change start */ 
     $rootScope.$on('$stateChangeStart', function(e, to, toParams, from, fromParams){ 
      e.preventDefault(); 
      $http 
       .get('/url') 
       .error(function(err){ 
        console.log(err); 
       }) 
       .then(function(response){ 
        if(response.data === 2){ 
         // e.preventDefault() 
         $state.go('main.home'); 
        } 
        // direct to default state 
       }) 
     } 
    }]); 
}); 

答えて

1

あなたは$ stateProviderConfigにresolveセクションを追加することができます。

解決の中で、データベースに要求を行い、必要な条件を確認できます。あなたがこのページにアクセスしないようにしたい場合は、$ state.go()を使って彼を他の場所にリダイレクトすることができます。

サンプル設定:resolve

.state({ 
    name: 'main.home', 
    template: 'index.html', 
    resolve: { 
     accessGranted: ['$http', '$state', '$q', 
      function($http, $state, $q) { 
       let deffered = $q.defer(); 
       $http({ 
        method: 'GET', 
        url: '/url' 
       }).then(function(data) { 
        if (data === 2) { 
         // ok to pass the user 
         deffered.resolve(true); 
        } else { 
         //no access, redirect 
         $state.go('main.unauthorized'); 
        } 
       }, function(data) { 
        console.log(data); 
        //connection error, redirect 
        $state.go('main.unauthorized'); 
       }); 
       return deffered.promise; 
      } 
     ] 
    } 
}); 

ドキュメントは、あなたがIE

+0

を次のように、それは素晴らしい作品、ありがとうございます。 (あなたの例で$ qも入力してください) – Timo

0
をサポートする必要はありません場合は、代わりに$ qをサービスの Promiseオブジェクトを使用することができます利用可能 here

注意です

この状況を処理する1つの方法は、以下のようにインターセプタを追加することです。

.config(function ($httpProvider) { 
     $httpProvider.interceptors.push('stateChangeInterceptor'); 
    }).factory('stateChangeInterceptor', function ($q, $window,$rootScope) { 
     return { 
      'response': function(response) { 
       var isValid = true;//Write your logic here to validate the user/action. 
       /* 
       * Here you need to allow all the template urls and ajax urls which doesn't 
       */ 
       if(isValid){ 
        return response; 
       } 
       else{ 
        $rootScope.$broadcast("notValid",{statusCode : 'INVALID'}); 
       } 

      }, 
      'responseError': function(rejection) { 
       return $q.reject(rejection); 
      } 
     } 
    }) 

その後、メッセージを扱う 'notValid'

.run(function($state,$rootScope){ 
     $rootScope.$on("notValid",function(event,message){ 
     $state.transitionTo('whereever'); 
    }); 
}) 
関連する問題