打字稿:如何从公共功能访问和更新类变量

时间:2018-11-29 15:46:17

标签: angularjs typescript

我正在尝试访问setRating()函数中的类变量的值,但控制台打印为“未定义”。

export class UserFeedbackComponent implements OnInit {    

  rating: number;    

  constructor() {
    this.rating = 3;
  }    

  ngOnInit() {
    //initial setup
    console.log("Rating " + this.rating);
    document.addEventListener('DOMContentLoaded', function() {

      let stars = document.querySelectorAll('.star');
      stars.forEach(function(star) {
        star.addEventListener('click', setRating);
      });

      let temps = parseInt(document.querySelector('.stars').getAttribute('data-rating'));
      console.log("Rating 2: " + this.rating);
      let target = stars[temps - 1];
      target.dispatchEvent(new MouseEvent('click'));   

    });    

  }


  function setRating(ev) {
    //Printing 'undefined' in console.log
    console.log('At top: ' + this.rating);
    let span = ev.currentTarget;
    let stars = document.querySelectorAll('.star');
    let match = false;
    let num = 0;
    stars.forEach(function(star, index) {
      if (match) {
        star.classList.remove('rated');
      } else {
        star.classList.add('rated');
      }
      //are we currently looking at the span that was clicked
      if (star === span) {
        match = true;
        num = index + 1;
      }

    });

    this.rating = num;

    console.log("value after update: " + this.rating)
    document.querySelector('.stars').setAttribute('data-rating', num.toString());    

  }

}

“更新后的值:”控制台日志打印“未定义”,除非this.rating分配给num。有人可以帮助我如何访问setRating()函数中rating变量的值以及如何更新其值吗?

2 个答案:

答案 0 :(得分:0)

这是一个上下文绑定问题,您必须将setRating函数绑定到类this上,否则它将使用自己的this,这与类{{1 }}无法访问this。您可以使用this.rating来实现。

您可以先将setRating.bind(this)更改为箭头函数,以便像这样继承上下文的DOMContentLoaded

this

然后,您可以对document.addEventListener('DOMContentLoaded', () => { // this.rating is visible here now ... }) 处理程序执行相同操作:

forEach

最后,您可以将外部函数的stars.forEach((star) => { // this.rating is visible here now too ... }); 绑定到类this

this

您的最终代码如下:

star.addEventListener('click', setRating.bind(this));

  

进一步的观察:您正在类中声明export class UserFeedbackComponent implements OnInit { rating: number; constructor() { this.rating = 3; } ngOnInit() { //initial setup console.log("Rating " + this.rating); document.addEventListener('DOMContentLoaded', () => { let stars = document.querySelectorAll('.star'); stars.forEach((star) => { star.addEventListener('click', setRating.bind(this)); }); let temps = parseInt(document.querySelector('.stars').getAttribute('data-rating')); console.log("Rating 2: " + this.rating); let target = stars[temps - 1]; target.dispatchEvent(new MouseEvent('click')); }); } function setRating(ev) { //Printing 'undefined' in console.log console.log('At top: ' + this.rating); let span = ev.currentTarget; let stars = document.querySelectorAll('.star'); let match = false; let num = 0; stars.forEach(function(star, index) { if (match) { star.classList.remove('rated'); } else { star.classList.add('rated'); } //are we currently looking at the span that was clicked if (star === span) { match = true; num = index + 1; } }); this.rating = num; console.log("value after update: " + this.rating) document.querySelector('.stars').setAttribute('data-rating', num.toString()); } },这完全没有必要,您可以将其声明为成员

function
     

然后,您甚至不必绑定它就可以像这样调用它:

export class UserFeedbackComponent implements OnInit { 
    ...
    setRating(ev) {
        ...
    }
}

答案 1 :(得分:0)

您不必在类中使用function关键字来定义函数。将其声明为班级成员,您应该可以正常访问它。这是Typescript类声明中的最佳做法。

EX:

export class UserFeedbackComponent implements OnInit {    

  rating: number;    

  constructor() {
    this.rating = 3;
  }    

  ngOnInit() {
    //initial setup
    console.log("Rating " + this.rating);
    ......................more code............
  }


  setRating(ev) {
    //Printing 'undefined' in console.log
    console.log(this.rating); //should work fine
    // do other stuff with class members
  }

}