18

アプリにユーザー認証チェックとアクセス チェック システムを実装しようとしていますが、障害が発生し続けています。今回は正しい方法で進めたと思いますが、最後のハードルが 1 つあります。

ちょっとした背景: すべてのコードを $rootScope.on($startChangeStart) に入れてみたところ、恐ろしくうまくいきました...しかし、うまくいきました。ルートは常にリダイレクトされましたが、バックエンドでの認証チェックにより、最初のリクエスト ページが 1/2 秒間表示され、その後毎回リダイレクト ページが表示されました。したがって、$startChangeStart 関数の開始時に evt.preventDefault() を呼び出してページの読み込みを「一時停止」しようとしましたが、機能しましたが、後でユーザーを元のルートに戻そうとすると、ルーターで無限ループが発生しました。

したがって、さらに調査し、多くのスタック投稿を読んだ後、「resolve:」が認証チェックを配置して、発生中にページが読み込まれないことを確認し、必要に応じて $ からユーザーをリダイレクトする適切な場所であると確信しています。 startChangeStart. ( $state と event は、解決関数に挿入しようとする私の試みでは常に未定義です) 勝利の組み合わせのようです。

私の問題: アプリのルート状態を解決しています: 'main'

これはコードの冗長性を避けるためでしたが、$stateChangeStart 関数からルート状態のプロパティにアクセスする方法、したがって解決結果にアクセスする方法を判断できません。toState は子状態ですが、fromState は前の状態または '^' ルートを持つ抽象状態です...

これを機能させるには、すべての子状態に解決を設定する必要がありますか、またはこの時点からルート状態にアクセスする方法はありますか?

アプリの基本設定:

angular.module('App', ['ui.router', 'ui.bootstrap', 'ui.event', 'AngularGM', 'ngResource'])
.config(['$urlRouterProvider', '$stateProvider', function($urlRouterProvider, $stateProvider){
    $urlRouterProvider
        .when('/home', '/')
        .when('', '/')
        .when('/sign-up/joe', '/sign-up')
        .otherwise('/');

    $stateProvider
        .state('main', {
            url: '',
            abstract: true,
            templateUrl: 'views/main.html',
            controller: 'MainCtrl',
            resolve: {
                checkAccess: ['accountService', function(accountService) {
                    accountService.checkAuth(function(){
                        accountService.checkAccess(function (access){
                            return access;
                        });
                    });
                }]
            }
        })
        .state('main.home', {
            url: '',
            abstract: true,
            templateUrl: 'views/home.html',
            controller: 'HomeCtrl'
        })
        .state('main.home.index', {
            url: '/',
            templateUrl: 'views/home/index.html'
        });


.run(['$rootScope', '$state', '$stateParams', 'accountService', function ($rootScope, $state, $stateParams) {
    $rootScope.$state = $state;
    $rootScope.$stateParams = $stateParams;
    $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
        console.dir(toState);
        console.dir(toParams);
        console.dir(fromState);
        console.dir(fromParams);
        if (!toState.checkAccess.allowed) {
            event.preventDefault();
            $state.transitionTo(toState.checkAccess.newState);
        }
    });
}]);

これは、2 つの状態オブジェクトに対する console.dir() 呼び出しからの出力です。

Object
 name: "main.home.index"
 templateUrl: "views/home/index.html"
 url: "/"
 __proto__: Object

Object
 controller: "PlacesCtrl"
 name: "main.places.search"
 templateUrl: "views/places.html"
 url: "/places"
 __proto__: Object

アップデート

おっと、AngularJS のバージョンが v1.2.0-rc.2 であることを忘れていました

$state.current console.dir()

Object
 abstract: true
 name: ""
 url: "^"
 views: null
 __proto__: Object
4

5 に答える 5

8

はい、$stateChangeStart関数からルート状態にアクセスできると思います。

純粋なAngularJSを使用する場合、私は通常使用しますcurrent.$$route

たとえば、次のルートを使用します。

.when('/home', {
  title:'Home',
  bodyClass: 'meetings',
  controler: 'HomeCtrl'
})

そのようにルート状態にアクセスできます

  $rootScope.$on('$routeChangeSuccess', function (event, current, previous) {

   if (current.$$route) {

     $rootScope.title      = current.$$route.title;

     $rootScope.bodyClass  = current.$$route.bodyClass;
   }

 });

と呼ばれているため、使用ui-router方法が少し異なり$state.currentます。また、ヒットしたルートに関連付けられたすべてのプロパティにアクセスできます (例: $state.current.url)。

だからあなたのコードでは、このようなものを持つことができます

  .run(['$rootScope', '$state', '$stateParams', function ($rootScope, $state, $stateParams) {

      $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
          console.log($state.current.url);
      });
  }]);
于 2013-10-02T18:15:31.737 に答える
1

を使用する必要はありませんresolve。私のソリューションを見てください:

app.run ($rootScope, $state, Auth, ngDialog) ->
  $rootScope.$on '$stateChangeStart', (e, to) ->
    if to.authRequired and not Auth.isAuthenticated()
      e.preventDefault()
      Auth.currentUser().then(
        (user) ->
          $state.go(to)
        (failure) ->
          $rootScope.storedState = to
          $state.go('main')
          ngDialog.closeAll()
          ngDialog.open
            template: 'modals/login.html'
            controller: 'loginCtrl'
            className: 'ngdialog-theme-default'
      )

angular_devisengDialogを使用していますが、これらはオプションであり、独自のユーザー サービスで実装できます。

于 2014-06-01T20:23:59.983 に答える
0

内からリダイレクトを行うことは可能accountServiceですか? ユーザーが checkAuth または checkAccess 関数に失敗したことを検出した場合、コールバックの実行を阻止し、ユーザーをエラー (またはログイン) ページにリダイレクトできます。

他に考慮すべきことは、誰かをログインページにリダイレクトして承認/認証を更新してから前の状態に戻したい場合は、ある種の変数/状態のキューを実装することです。

于 2013-12-10T17:18:35.533 に答える
0

解決時にデフォルトの空のオブジェクトで状態を初期化すると、 内で操作できるようになります$stateChangeStart

$stateProvider
  .state 'home',
    url: "/"
    resolve: {}

...

  $rootScope.$on '$stateChangeStart', (e, toState, toParams, fromState, fromParams) ->
    toState.resolve.x = ->
      $timeout ->
        alert "done"
      , 3000

https://github.com/angular-ui/ui-router/issues/1165を参照してください

于 2014-08-29T01:12:30.533 に答える