【问题标题】:Local variable becomes undefined on refresh. Angular 2局部变量在刷新时变为未定义。角 2
【发布时间】:2017-09-24 02:13:12
【问题描述】:

我正在开发一个聊天应用程序。有一个 chat.component.ts 连接到服务并获取“消息”和“显示名称”。

在 chat.component.html 中绑定 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),它是未定义的。

有趣的是,'messaages' 一直在正常工作。

我认为这更像是一个概念性问题,我正在努力弄清楚为什么会发生这种情况以及如何解决它。这个问题我也找不到更好的标题了。

更新,这是 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;
  }
}

【问题讨论】:

  • 您的组件没有显示在任何地方分配的this.displayName 值。所以console.log(this.AF.displayName)console.log(this.displayName) 返回undefined 时正确显示是有意义的。
  • 很抱歉,我发布了一个经过编辑的代码版本。我会编辑以避免混淆。
  • 感谢更新。如果问题仍然存在,您能否也发布您的 AFService?
  • 好的,我已经更新了。我没有搞砸的服务我尝试添加一个 getDisplayName() 函数,但没有奏效。

标签: javascript angular firebase


【解决方案1】:

因此,虽然我同意 amal 的评论,但看不到 this.displayName 的设置位置。我以前遇到过这个问题。由于没有以前的组件,您将需要一种方法让页面保存显示名称。我通常使用本地存储来执行此操作。

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

检索数据和

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

检索数据。话虽如此,我看不到您在哪里设置域名,这会导致问题。我正在回答您对刷新的一般概念性问题。

【讨论】:

  • 雷格曼感谢您的帮助。我一直试图解决这个问题一段时间。您会建议这是解决此问题的“理想”方式吗?
  • 我不会说它是理想的解决方案,但如果这有意义的话,这就是我处理它的方式。它应该可以解决您的问题,但可能有一种更优雅的方式来处理这个问题,但此时,这取决于您的整个应用程序的设置方式。所以我会推荐它作为解决方案
【解决方案2】:

如果我理解正确,您应该在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
        }
     });
}

【讨论】:

    【解决方案3】:

    好的。现在很清楚为什么 messages 可用而 displayName 不在 ChatComponent 中。在 AFService 的构造函数中,您正在设置 messages 的值,但不是 displayName。因此,当该服务在您的 ChatComponent 中实例化时,您将组件的 messagesdisplayName 属性设置为来自 AFService 的属性。但是 AFService 在它自己的构造函数中只有 messages 的值。 因此,解决问题的简单方法是在服务的构造函数中定义 displayName 的值。 如果需要从其他地方(例如异步)获取该值,则需要基于此重构组件或服务的代码。 无论哪种方式,请确保您引用了在其构造函数中实例化的 AFService 的某些属性,同时在 ChatComponent 中引用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-01
      • 2012-03-29
      • 2013-04-29
      • 2013-04-24
      • 2018-08-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多