4

現在、ログインしているユーザーがアプリでログイン ページにアクセスしようとすると、ログイン ページからリダイレクトしようとしています。ログイン ページに関連付けられたコントローラ -Login_controller認可サービスの関数を呼び出します - Authorisation_service.isLoggedIn()。このサービスが true を返す場合、ユーザーはログインした概要ページにリダイレクトされます。

コンソールにログを記録すると、サービスが true を返す前に、サービスから返された値が未定義であることが条件文で既に宣言されていることがわかります。その後、サービスは true を返しますが、手遅れです。

コントローラーの条件ステートメントがサービスからの戻り値を待機するようにするにはどうすればよいですか?

Authorise_service.js

myApp.factory('Authorise', ['User', '$http', '$location', '$rootScope', function( User, $http, $location, $rootScope ) {
    return {
        isLoggedIn: function() {
            if( ((sessionStorage.username && sessionStorage.authKey) && (sessionStorage.username !== "null" && sessionStorage.authKey !== "null")) || ((localStorage.username && localStorage.authKey) && (localStorage.username !== "null" && localStorage.authKey !== "null" )) ) {
                if( sessionStorage.username ) {
                    var usernameLocal = sessionStorage.username;
                    var authKeyLocal = sessionStorage.authKey;
                } else {
                    var usernameLocal = localStorage.username;
                    var authKeyLocal = localStorage.authKey;
                }
                //pass to server
                var user = User.query({ usernameLocal: usernameLocal, authKeyLocal: authKeyLocal }, function(user) {
                    if( user.loginSuccess === 1 ) {
                        return true;
                    } else {
                        return false;
                    }
                });
            } else {
                return false;
            }
        }
    };
}]);

Login_controller.js

myApp.controller( 'Login_controller', function( Authorise, $scope, $location ) {
    if( Authorise.isLoggedIn() === true ) {
        console.log("Authorise.isLoggedIn() = true");
        $location.path('/teach/overview');
    }
});
4

2 に答える 2

5

Smkは正しいです。サーバーからまだ返されていないデータに依存しようとしている可能性があります。ここでの重要な問題は「まだ」です。おそらくデータがサーバーから適切にフェッチされているため、準備が整う前に結果を参照しようとしているだけです。これが真実かどうかを確認するには、コールバックを追加するだけconsole.log(user)ですUser.query(...)

Smkは、正しいアプローチを示しました。代わりにPROMISEAPIを使用してください。基本的に、promiseは、サーバーから結果の準備ができたときにいくつかのアクションを実行するためにさらに使用できるオブジェクトです。これを説明するために:

function myFunc() {
   var result = false;

   // You are calling async request to the server, so the execution won't wait for the
   // results. It will simply fire server request and proceed to next lines.
   serverCall(function(srvResponse){

      result = srvResponse.everythingIsGood; // This will be called after the whole method finishes!
   });

   return result; // This will MOST PROBABLY return 'false' all the times.
}

そしてこれを行う適切な方法:

function theRealLogicYouWantToDo(result) {
   if (result) {
      // ...
   } else {
      // ...
   }
}

serverCall(function(srvResponse) {
   theRealLogicYouWantToDo(srvResposne.everythingIsGood);
});

これは、JQUERYでのこれらすべてについての素晴らしいチュートリアルです。サーバー呼び出しだけでなく、JSの他のいくつかの場所でも使用されます。それを学ぶのは良いことです。

于 2013-03-08T06:32:18.930 に答える
3

promiseを返す必要があります。

angularjs サービスは promise を返すことができ、コントローラでその値をテストできます。

于 2013-03-08T05:34:52.777 に答える