2017-12-03 6 views
0
router.get('/isloggedin', (req, res) => { 
    if(req.user){ 
     return res.json({'isLogged': true}); 
    } 
    return res.json({'isLogged': false}); 
}) 

上記からわかるように、私のノードのバックエンドは、ユーザーが存在するかどうかによってJSON応答を送信します。私のフロントエンドでは、私はそれが真実か偽であるかに応じてテンプレートで使うことができるユーザサービスの変数をトグルしたいと思っていますが、私はそれに多くの問題を抱えています。IsLoggedIn APIを使用した角型のHTTPサービス

import { Injectable } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 
import 'rxjs/add/operator/map'; 

@Injectable() 
export class AuthService { 
    constructor (private http: Http) {} 
    isLoggedIn(){ 
     this.http.get("http://localhost:3000/auth/isloggedin") 
     .map(res => res.json()).toPromise(); 
    } 

} 

これは私が今持っているすべてです。このようなことをどうやって設定するのですか?私はテンプレートで私の認証サービスから変数を使用できるようにしたいが、私は関数に登録すると無限ループなどの問題にぶつかる。

HTMLコード:

<div style="text-align:center"> 
    <h1> 
    Welcome to {{ title }}! 
    </h1> 
    <img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg=="> 
</div> 
<h2>Here are some links to help you start: </h2> 
<ul> 
    <li *ngIf="authService.isLoggedIn() | async"> 
    <h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2> 
    </li> 
    <li> 
    <h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2> 
    </li> 
    <li> 
    <h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2> 
    </li> 
</ul> 
+0

これまでにconsole.logに呼び出しから戻ってきたデータはありますか? –

+0

私はobservableを購読したり、それをpromiseに変換したりしますが、ページロードの開始時に1つのhttp応答が必要です。私が望むのは、ユーザーステータスを取得し、それを変数に格納し、コード内で使用することだけです。 –

+0

サブスクリプションコードを表示できますか? –

答えて

0

さてさて、いくつかのコードでそれをまとめるために、ここでの可能な解決策です。

あなたは現在、戻り値isLoggedIn()をhtmlテンプレートにバインドしています。残念ながら、あなたの関数はおそらく角が何度も何度も何度も何度もそれを呼び出そうとしている(あなたはバックエンドを呼び出していますが、あなたの関数にはreturnはありません)何も返しません。しかし、あなたが呼び出しているオブザーバブルを返すとしても、かなり時間がかかっていて実際には複雑な呼び出しであり、結局何度も呼び出す必要はないので、依然として最適ではありません。コード内に複数の*ngIfセクションがあり、すべてがログイン状態に依存しているとします。これは、あなたのテンプレート内のすべての*ngIf="authService.isLoggedIn() | async"に対して、angleがバックエンドを呼び出すことを意味します。それはかなりのオーバーヘッドです。

こちらのケースでは、ログイン情報を一度にして、変数の状態を安全にする方がはるかに良いでしょう。このためにあなたのサービスのコンストラクタを使うことができます。角度依存性注入システムでは、サービスはシングルトン(正しく使用される場合)とみなされます。私はangular tutorialから

と言っています。サービスはインジェクタのスコープ内にあるシングルトンです。与えられたインジェクタには、サービスの最も多くのインスタンスが にあります。

ルートインジェクタが1つしかなく、UserServiceにinjectorという が登録されています。したがって、アプリケーション全体に1つのUserServiceインスタンス が存在する可能性があり、UserServiceを注入するすべてのクラスは、この サービスインスタンスを取得します。

つまり、サービスのコンストラクタは1回だけ呼び出されます。したがって、コンストラクタの中でバックエンド呼び出しを行うかどうかを確認することができます。サービスが最初に行うことであり、それが実行されるのは時間だけです。これは私たちには良いことです。バックエンドの呼び出しが少なくて済みます。結果は、公共の使用のために変数に保存されます。

@Injectable() 
export class AuthService { 
    constructor (private http: Http) { 
     // one time call to get the login status 
     this.http.get("http://localhost:3000/auth/isloggedin").subscribe(data=>{ 
      // save the state in the variable 
      this.isLogged = (<any>data).isLogged; 
     }); 
    } 

    // this is our variable 
    isLogged:boolean =false; 
} 

今すぐ本当に素早くhtmlテンプレートに入ります。私たちはもうバインディングとしてisLoggedIn()を使用していません。サービスの作成後に設定している変数を使用することができます。

<li *ngIf="authService.isLogged"> 
    <h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2> 
</li> 

いいですね。ここで、ログイン状態をチェックする必要がある他のhtmlタグがある場合、複数の呼び出しを増やすことなく、まったく同じ変数を使用できます。

総集編

確認コードが動作するだけでなく、より少ない時間と(帯域幅などの)他のリソースを取っているだけでなくことを確認するように変更する必要いくつかのもの。そのために我々は作られていることを確認して:

  • isLoggedIn要求は一度だけ行われる - >コンストラクタ
  • 状態に置か - >isLoggedIn要求が最初に呼び出された
  • もはやテンプレートにバインドされていません再びバックエンドを要求wihout複数回参照することができます - >テンプレートで参照される変数にリコールセーフ

サイドノート

サービス内のこの変数を使用すると、ログインとログアウトは非常に簡単です。フロントエンドを通してログインするとき、ログインが成功したときに変数をtrueに設定できます。あなたがログアウトすると、それを偽に設定することができます。

login(username, password) { 
    this.http.post("http://localhost:3000/auth/login", {username: username, password: password}).map(res=>res.json()).subscribe(() => { 
     this.isLogged=true; 
    }); 
} 
logout() { 
    this.http.post("http://localhost:3000/auth/logout", {}).map(res => res.json()).subscribe(() => { 
     this.isLogged = false; 
    }); 
} 
関連する問題