2017-09-24 4 views
0

私はチャットアプリケーションで作業しています。 chat.component.tsはサービスに接続し、 'メッセージ'と 'displayName'を取得します。 chat.component.htmlでローカル変数はリフレッシュ時に未定義になります。角2

は次のようにのdisplayNameを結合しています: <p>You are logged in as: {{displayName}}</p>

これはchat.component.tsは、次のようになります。

import { Component, OnInit, AfterViewChecked, ViewChild, ElementRef } from '@angular/core'; 
 
import { AfService } from '../af.service'; 
 
import { FirebaseListObservable } from 'angularfire2/database'; 
 

 
@Component({ 
 
    selector: 'app-chat', 
 
    templateUrl: './chat.component.html', 
 
    styleUrls: ['./chat.component.css'] 
 
}) 
 
export class ChatComponent implements OnInit { 
 

 
    public newMessage: string; 
 
    public messages: FirebaseListObservable<any>; 
 
    public displayName: string; 
 

 
    constructor(public AF: AfService) { 
 
    this.messages = this.AF.messages; 
 
    this.displayName = this.AF.displayName; 
 
    } 
 

 
    ngOnInit() {} 
 

 
    @ViewChild('scrollMe') private myScrollContainer: ElementRef; 
 

 
    ngAfterViewChecked() { 
 
    this.scrollToBottom(); 
 
    } 
 

 
    scrollToBottom(): void { 
 
    try { 
 
     this.myScrollContainer.nativeElement.scrollTop = this.myScrollContainer.nativeElement.scrollHeight; 
 
    } catch(err) { console.log('Scroll to bottom failed yo!')} 
 
    } 
 

 
    isMe(email) { 
 
    if(email == this.AF.email) 
 
     return true; 
 
    else 
 
     return false; 
 
    } 
 

 
    sendMessage(){ 
 
    this.AF.sendMessage(this.newMessage); 
 
    this.newMessage = ''; 
 
    } 
 
}

AfServiceのdisplayNameプロパティが前のコンポーネントから設定されています。私はのdisplayNameでゼロからアプリケーションを介して働いて、ログイン

が提供されています:

は今、これが問題です。しかし、chat.component.htmlページを更新すると、displayNameは未定義になります。たとえば、console.log(this.AF.displayName)を実行すると、表示されるはずですが、console.log(this.displayName)を実行すると定義されません。

興味深いのは、「メッセージ」が正しく機能し続けることです。

これは概念的な疑問であり、なぜこれが起こり、どうやって解決するのかを考えていると思います。また、私はこの質問のより良いタイトルができませんでした。

更新、これはAfServiceです:

import { Injectable } from '@angular/core'; 
 
import { AngularFireDatabase } from 'angularfire2/database'; 
 
import { AngularFireAuth } from 'angularfire2/auth'; 
 
import { FirebaseListObservable } from 'angularfire2/database'; 
 
import { Observable } from 'rxjs/Observable'; 
 
import * as firebase from 'firebase/app'; 
 

 
@Injectable() 
 
export class AfService { 
 

 
    user: Observable<firebase.User>; 
 
    messages: FirebaseListObservable<any>; 
 
    displayName: string; 
 
    email: string; 
 

 
    constructor(public db: AngularFireDatabase, public afAuth: AngularFireAuth) { 
 
    this.messages = this.db.list('messages'); 
 
    } 
 

 
    loginWithGoogle(){ 
 
    return this.afAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider()); 
 
    }; 
 

 
    logout(){ 
 
    this.afAuth.auth.signOut(); 
 
    }; 
 

 
    sendMessage(text) { 
 
    var message = { 
 
     message: text, 
 
     displayName: this.displayName, 
 
     email: tis.email, 
 
     timestamp: Date.now() 
 
    }; 
 
    this.messages.push(message); 
 
    }; 
 

 
    getDisplayName() { 
 
    return this.displayName; 
 
    } 
 
}

+1

コンポーネントにはどこにも割り当てられていない「this.displayName」値が表示されません。だから 'console.log(this.AF.displayName)'が正しく表示されるのに対して、 'console.log(this.displayName)'は 'undefined'を返すのが理にかなっています。 – amal

+0

私は非常にごめんなさい、私は編集されたコードのバージョンを投稿しました。混乱を避けるために編集します。 –

+0

更新していただきありがとうございます。質問がまだ残っている場合は、AFServiceも投稿してください。 – amal

答えて

2

だから私はアマルのコメントに同意し、this.displayNameが設定されている場所を確認しながら、カント。私は以前この問題に遭遇しました。前のコンポーネントがないので、ページに表示名を保存する方法が必要です。私は通常これを行うためにローカルストレージを使用します。データを取得するには、データと

this.displayName= JSON.parse(localStorage.getItem('displayName')); 

を取得するために

 localStorage.setItem('displayName',JSON.stringify(this.displayName)); 

。それは、私はあなたが問題を引き起こすドメイン名を設定しているのか分からないと言われています。私はリフレッシュについてあなたが持っている一般的な概念的な質問に答える。

+0

レグマンは助けてくれてありがとう。私はしばらくこの問題を回避しようとしてきました。この問題を解決するための「理想的な」方法であることをお勧めしますか? –

+0

私はそれを理想的な解決策とは言いませんが、それが理にかなっていれば、私はそれを扱っています。それはあなたの問題を解決するはずですが、これを処理するためのよりエレガントな方法があるかもしれませんが、その時点では、全体のアプリの設定方法によって異なります。だから私は解決策としてそれをお勧めします – Legman

0

私が正しく理解している場合、あなたはあなたのAfService

constructor(public db: AngularFireDatabase, public afAuth: AngularFireAuth) { 
    this.messages = this.db.list('messages'); 

    this.afAuth.auth.subscribe(res => { 
     if (res && res.uid) { 
      //user logged in 
      this.email= res.email; 
      this.displayName = res.displayName; 
     } else { 
      //user not logged in or logged out 
     } 
    }); 
} 
0

オーケーで認証サービスに加入する必要があります。 displayNameはあなたのチャットコンポーネントに含まれていませんが、messagesが利用可能になった理由は明らかです。あなたのAFServiceのコンストラクタでは、messagesの値を設定しますが、displayNameの値は設定しません。したがって、そのサービスがChatComponent内でインスタンス化されている間は、コンポーネントのmessagesおよびdisplayNameプロパティをAFServiceのプロパティに設定しています。しかし、AFServiceはそれ自身のコンストラクター内でmessagesの値しか持っていません。 問題の簡単な修正は、サービスのコンストラクター内でも定義されたdisplayNameの値を持つことになります。 その値を非同期的に他の場所からフェッチする必要がある場合、その値に基づいてコンポーネントまたはサービスのコードをリファクタリングする必要があります。 どちらの方法でも、コンストラクタ内でインスタンス化されたAFServiceのプロパティをChatComponentで参照していることを確認してください。

関連する問題