回调中变量初始化期间未定义属性的困难

Difficulties with undefined properties during variable initialization in callback

我在 NodeJS 中有一个 API rest 服务器,带有 express Framework,它与我用 Angular7 制作的 Front 进行通信。服务器存储和发送一些分数对象,模型正反面相同。

问题是我遇到了以下错误:

ERROR TypeError: Cannot set property 'userScore' of undefined
ERROR TypeError: Cannot read property 'highScore' of undefined
ERROR TypeError: Cannot set property 'highScore' of undefined

我的错误出现的组件:

import {AfterViewInit, Component, ElementRef, HostListener, OnInit, 
ViewChild} from '@angular/core';
import {ScoreService} from './services/score.service';
import {Score} from './models/score';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit, AfterViewInit {
  contentScores: {
    highScore: number,
    userScore: Score
  };
  scroll: boolean;
  badgeHidden: boolean;
  private yOffSet: any;

  @ViewChild('navbar') navElement: ElementRef;

  constructor(private score: ScoreService) {
    this.scroll         = false;
    this.badgeHidden    = true;
  }

  ngOnInit(): void {
    this.score.getHighScore().subscribe( score => {
      console.log('Score value: ' + score.score);
      console.log('Object: ' + score);
      this.contentScores.highScore = score.score;
    });
    this.score.getScoreOnIp().subscribe( score => {
      console.log('Score value: ' + score.score);
      console.log('Object: ' + score);
      this.contentScores.userScore = score;
    });
  }

  ngAfterViewInit(): void {
    this.yOffSet = this.navElement.nativeElement.offsetTop;
  }

  onClickReset(): void {
    console.log('----------INFO------------');
    console.log(this.contentScores.highScore);
    console.log(this.contentScores.userScore.score);
    console.log(this.contentScores.userScore._id);
    console.log('--------------------------');
    this.score.deleteScore(this.contentScores.userScore._id);
  }

  @HostListener('window:scroll', ['$event'])
  onWindowScroll(): void {
    const currYOffset = window.pageYOffset;

    if (this.yOffSet < currYOffset) {
      this.scroll = true;
    } else {
      this.scroll = false;
    }
  }
}

以及调用变量时在视图中的位置:

<p class="dropdown-item-text">Le meilleur score enregistré est actuellement: <span class="warn-content">{{ contentScores.highScore }}</span></p>
            <p class="dropdown-item-text">Votre meilleur score est: <span class="warn-content">{{ contentScores.userScore.score }}</span></p>

我不明白为什么我不能在 api 调用中用值实例化一个未定义的对象。请注意,console.log 显示了值,因此从恢复的数据来看这不是问题,问题是关于存储值的对象的声明。

我是 Angular7 开发的新手,所以很抱歉,如果答案可能很明显,请提前为我的英语道歉,我知道它不是很好。

contentScores 尚未初始化。

如果你用一个空对象初始化它,那么它就可以工作

contentScores: {
    highScore: number,
    userScore: Score
  } = {};

这是由于代码如何转译为 Javascript。看看这个 Typescript 代码:

class Greeter {
    contentScores: {
        highScore: string,
    };
    constructor(message: string) {
        this.contentScores.highScore = message;
    }
}

let greeter = new Greeter("world");

会变成这个Javascript代码:

var Greeter = /** @class */ (function () {
    function Greeter(message) {
        this.contentScores.highScore = message;
    }
    return Greeter;
}());
var greeter = new Greeter("world");

如您所见,this.contentScores 未在任何地方初始化。

另一方面,如果您将其创建为一个空对象,那么它将被正确初始化:

class Greeter {
    contentScores: {
        highScore: string,
    } = {};
    constructor(message: string) {
        this.contentScores.highScore = message;
    }
}

let greeter = new Greeter("world");

变成

var Greeter = /** @class */ (function () {
    function Greeter(message) {
        this.contentScores = {};
        this.contentScores.highScore = message;
    }
    return Greeter;
}());
var greeter = new Greeter("world");