2016-08-12 7 views
0

私は初心者です。私のPHPバックエンドからデータを取得し、コントローラを更新するファクトリを設定しようとしています。ここに私の基本的なコードは次のとおりです。サービスから返されたオブジェクトにアクセスできますが、そのプロパティにアクセスすると未定義です

app.controller('headerCtrl', ['$scope', 'sessionStatus', function($scope, sessionStatus){ 

    $scope.sessionStatus = sessionStatus.status(); 

    console.log($scope.sessionStatus); 

}]); 

工場

app.factory('sessionStatus', ['$http', function($http){ 
    return { 
     status:function(){ 
      var status = {}; 
      $http.get('/game_on/api/api.php?session-status') 
      .then(function(response){ 
       angular.copy(response.data, status); 
      }); 
      return status; 
     } 
    }; 
}]); 

コントローラは、これは私に、コンソールに次のようになります:

Object{} 
    session:"false" 

しかし、ときに私cを調整するセッションプロパティの値を次のように記録します:

console.log($scope.sessionStatus.session); 

私は単にコンソールで定義されていません。

私は間違っていますか?

EDIT遅滞の私の明確なブランドに苦しんでいる誰のために

が、ここで私が達した結論だ:

問題の主な原因は、私がアクセスしようとしてきたということです(つまり.then()の実行が終了する前に)$ httpサービスによって返された非同期的に生成された情報が返されます。これは、未定義のデータが生成されているため、コントローラではconsole.log()が呼び出されます。

$ timeoutサービスを使用して、console.log()の呼び出しを遅延させることができました。その結果、データが正しくコンソールに記録されました。

$timeout(function(){ 
    console.log($scope.sessionStatus.session); 
}, 2000); // logs "false" to the console like originally expected 

私の以前の考えは、私は、コントローラ内で可能な限り私のファクトリメソッドの呼び出しがのように短くし、その後、その呼び出しの外でその結果に基づいて行動すべきであるということでした。これは、明らかに悪い考えです。.then()が存在するため、要求が完了した瞬間に非同期要求の結果に応じることができます。後知恵で

このすべてはそれほど明白ようだが、うまくいけば、この説明は、将来的に他の誰かを助け...私が受け取ったすべての答えのための

おかげで、彼らは大きな助けでした!

+0

にconsole.logが非同期動作であり、常にあなたはそれが期待される正確な時刻に値を記録しません。あなたのコントローラで、 'console.log($ scope.sessionStatus);'を 'console.log(JSON.stringify($ scope.sessionStatus));'に変更したら、それは何から出力されますか? 編集:プロミスが返される前にあなたのconsole.logが完了していると思われます。そのため、そのプロパティにアクセスできないのです。 –

+0

@IthinkIcancode - はい、あなたは正しいと思われます。 JSON.stringify()は空のオブジェクトを出力します。 – talvorn

+0

@IthinkIcancode - $ timeoutを使用してconsole.log呼び出しで2秒の遅延を設定することで希望の値を記録できたので、非同期性が原因であるようです。 – talvorn

答えて

0

JavaScriptは非同期であるため、http応答まで待機せずにステータスを返します。なぜそれがnullを返すか。

app.factory('sessionStatus', ['$http', function($http) { 
    var factory = { 
    status: status 
    }; 

    return factory; 

    function status() { 
    return $http.get('/game_on/api/api.php?session-status'); 
    } 
}]); 

その後コントローラに:

app.controller('headerCtrl', ['$scope', 'sessionStatus', function($scope, sessionStatus) { 
    function getSuccess(response) { 
    $scope.sessionStstus = response.data; 
    } 

    function getError(response) { 
    console.log('error'); 
    } 

    sessionStatus.status() 
    .then(getSuccess) 
    .catch(getError); 

    console.log($scope.sessionStatus); 
}]); 
0

のようなものを試してみてくださいここのコードに。まず、私は約束を解決し、サービスではなくコントローラの価値を割り当てることを提案します。次に、結果オブジェクトにAngular.Copyを使用する必要はなく、単に変数を代入することができます。その後、増築、単にこのような何かを試してみてください:

app.factory('sessionStatus', ['$http', function($http){ 

    return {status: $http.get('/game_on/api/api.php?session-status')} 

}]); 

app.controller('headerCtrl', ['$scope', 'sessionStatus', function($scope, sessionStatus){ 

    sessionStatus.status.then(function(result){ 
     $scope.sessionStatus = result.data; //or some property on result 
    }); 

}]); 
1

あなたが作ることができるの変更のカップルがありますあなたのfactoryから約束を返すようにしてください。この

app.factory('sessionStatus', ['$http', function($http){ 
      return { 
       status:function(){ 
       $http.get('/game_on/api/api.php?session-status') 
       } 
      }; 
     }]); 

     app.controller('headerCtrl', ['$scope', 'sessionStatus', function($scope, sessionStatus){ 

      $scope.sessionStatus = sessionStatus.status().then(function(response) { 
       console.log(response); 
     }); 


    }]); 
+0

あなたの答えをありがとう。私は以前これを解決策として試しましたが、promiseのthenメソッドの外で割り当てられた$ scope変数の値にアクセスすることができませんでした。 OPのコメントで指摘したように、これは非同期であると思われますが、実際にはthenメソッドの外でこれらの値にアクセスすることが可能かどうかを教えてください。そのような値がその中に置かれて、約束が返されたときにのみ実行されるようにします。ありがとう。 – talvorn

+0

あなたは常にreturnメソッドでコードを持つ必要があります。今では、あなたのアプリケーションでその作業を行うためのいくつかの創造的な方法を見つけることができます。ほとんどの場合、アプリケーションの設計をどのようにして決定したかが分かります。その結果、将来的に価値を上げるのではなく、価値を適切に更新することが約束されています。私はいくつかの例を示すためにフィドルをまとめました。 [こちらをチェックしてください](http://jsfiddle.net/kg6qevh0/)。乾杯 –

関連する問題