我正在尝试访问函数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());
}
}
">更新后的值:"控制台日志打印"未定义",除非将此.rating分配给 num。有人可以帮我如何在 setRating() 函数中访问评级变量的值以及如何更新其值吗?
这是一个上下文绑定问题,您必须将setRating
函数绑定到类this
否则它将使用自己的this
,这与无法访问this.rating
this
类不同。您可以通过使用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) { ... } }
然后你甚至不需要绑定它来这样称呼它:
star.addEventListener('click', ev => this.setRating(ev));
您不必在类中使用function
关键字定义函数。 将其声明为类成员,您应该能够正常访问它。这是 Typescript 类声明中的最佳实践。
前任:
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
}
}