Javascript 范围界定';这';打字
我有一个非常简单的类,但在Typescript中定义“this”时已经遇到了麻烦: 打字稿Javascript 范围界定';这';打字,javascript,typescript,Javascript,Typescript,我有一个非常简单的类,但在Typescript中定义“this”时已经遇到了麻烦: 打字稿 /// <reference path='jquery.d.ts' /> /// <reference path='bootstrap.d.ts' /> module Problem { export class Index { detailsUrl: string; constructor() { $('.prob
/// <reference path='jquery.d.ts' />
/// <reference path='bootstrap.d.ts' />
module Problem {
export class Index {
detailsUrl: string;
constructor() {
$('.problem-detail-button').click((e) => {
e.preventDefault();
var $row = $(this).closest('tr'); //this must be that of the callback
var problemId: number = $row.data('problem-id');
$.ajax({
url: this.detailsUrl, //this must be the instance of the class
data: { id: problemId },
type: 'POST',
success: (result) => {
$('#details-modal-placeholder').html(result);
$('#details-modal-placeholder modal').modal('show');
},
})
});
}
}
}
现在的问题是这条线
var $row = $(this).closest('tr'); //this must be that of the callback
这条线呢
this.detailsUrl, //this must be the instance of the class
“this”含义上的冲突
如何处理“this”的混合体?您需要回到javascript的标准方式。i、 e将变量存储为:
var self = this;
然后您可以使用函数
而不是()=>
,并使用this
访问回调中的变量和self
访问类的实例
以下是完整的代码示例:
module Problem {
export class Index {
detailsUrl: string;
constructor() {
var self = this;
$('.problem-detail-button').click(function(e){
e.preventDefault();
var $row = $(this).closest('tr'); //this must be that of the callback
var problemId: number = $row.data('problem-id');
$.ajax({
url: self.detailsUrl, //this must be the instance of the class
data: { id: problemId },
type: 'POST',
success: (result) => {
$('#details-modal-placeholder').html(result);
$('#details-modal-placeholder modal').modal('show');
},
})
});
}
}
}
// Creating
var foo:any = {};
foo.x = 3;
foo.y='123';
var jsonString = JSON.stringify(foo);
alert(jsonString);
// Reading
interface Bar{
x:number;
y?:string;
}
var baz:Bar = JSON.parse(jsonString);
alert(baz.y);
以及生成的javascript:
var Problem;
(function (Problem) {
var Index = (function () {
function Index() {
var self = this;
$('.problem-detail-button').click(function (e) {
e.preventDefault();
var $row = $(this).closest('tr');
var problemId = $row.data('problem-id');
$.ajax({
url: self.detailsUrl,
data: {
id: problemId
},
type: 'POST',
success: function (result) {
$('#details-modal-placeholder').html(result);
$('#details-modal-placeholder modal').modal('show');
}
});
});
}
return Index;
})();
Problem.Index = Index;
})(Problem || (Problem = {}));
var foo = {
};
foo.x = 3;
foo.y = '123';
var jsonString = JSON.stringify(foo);
alert(jsonString);
var baz = JSON.parse(jsonString);
alert(baz.y);
明确声明that=this
,这样您就有了对that.detailsUrl
的引用,然后
不要对click处理程序使用粗箭头,这样您就可以获得回调的正确this
范围
.通常,只要变量在我想要的范围内,我就会将它绑定到变量上 但是,您要查找的
此
如下所示:
constructor() {
var class_this=this;
$('.problem-detail-button').click(function (e) {
e.preventDefault();
var callback_this=e.target;
如果您只支持具有
.addEventListener
的浏览器,我建议您使用它将数据与元素关联起来
我将只给出一个简单的示例,而不是实现您的代码
function MyClass(el) {
this.el = el;
this.foo = "bar";
el.addEventListener("click", this, false);
}
MyClass.prototype.handleEvent = function(event) {
this[event.type] && this[event.type](event);
};
MyClass.prototype.click = function(event) {
// Here you have access to the data object
console.log(this.foo); // "bar"
// ...and therefore the element that you stored
console.log(this.el.nodeName); // "DIV"
// ...or you could use `event.currentElement` to get the bound element
};
因此,这种技术为您提供了元素和数据之间有组织的耦合
即使您需要支持旧IE,也可以使用.attachEvent()
对其进行填充
因此,要使用它,只需在设置数据时将元素传递给构造函数
new MyClass(document.body);
如果所有的逻辑都在你的处理程序中,你甚至不需要保留对你创建的对象的引用,因为处理程序通过
this
自动获取它,但是我有一些不同的建议
而不是:
var $row = $(this).closest('tr'); //this must be that of the callback
考虑使用:
var $row = $(e.currentTarget).closest('tr');
在本例中,您可以在jQuery回调中使用this
的任何地方访问一个可以替代使用的函数参数。我建议使用这些参数而不是这个
更干净(其中“cleaner”被定义为更具表现力,在未来的维护中不太可能变成bug)
查查。
提醒你还有另一种方法。ooooooo,想看看大脑对这一方法的看法吗!这似乎与所有其他TS+“这个”问题不同,因此……实际上,我的演示中也提到了这个案例:@BasaratAli我认为该演示中可能有很多很棒的信息,但很难理解这种格式。我觉得幻灯片应该附有一段视频或至少是一篇更具描述性的文章。我建议这个问题的读者研究上面的链接(basarat.github.io/TypeScriptDeepDive/#/this),因为它解释了Typescript结合箭头功能对“this”的处理。因此,您可以理解为什么接受的答案是解决方案。当然:)为什么评论必须是15个字符?非常好+一丁点儿。点击回答。+1,因为我认为我们或多或少在同一时间得到了相同的答案。@RyanCavanaugh字符限制很有趣-尤其是它包含了姓名标签-所以我可以用你的姓名标签进行评论,但我不能说“确定”。这很好,我不知道
handleEvent
和事件侦听器接口。但似乎您应该始终在handleEvent
中使用event
(或e
),否则e
将是未定义的。这太完美了。。。我应该看看的。周五晚些时候:)它可以工作,但我希望Typescript最终摆脱“that=this”的解决方法,并像其他任何oop语言一样使用“this”:(我同意target会解决这个确切的问题,但它带来了一个关于混合“this”范围的更大问题
var $row = $(this).closest('tr'); //this must be that of the callback
var $row = $(e.currentTarget).closest('tr');
module Problem {
export class Index {
constructor() {
$('.classname').on('click',$.proxy(this.yourfunction,this));
}
private yourfunction(event){
console.log(this);//now this is not dom element but Index
}
}
}