我有一个非常简单的类,但在Typescript中定义'this'已经遇到了痛苦:
打字稿
/// <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');
},
})
});
}
}
}
的Javascript
var Problem;
(function (Problem) {
var Index = (function () {
function Index() {
var _this = this;
$('.problem-detail-button').click(function (e) {
e.preventDefault();
var $row = $(_this).closest('tr');
var problemId = $row.data('problem-id');
$.ajax({
url: _this.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 $row = $(this).closest('tr'); //this must be that of the callback
和这一行
this.detailsUrl, //this must be the instance of the class
'this'意思冲突
你如何处理'this'的混合?
答案 0 :(得分:12)
module Problem {
export class Index {
detailsUrl: string;
constructor() {
var that = 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: that.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');
},
})
});
}
}
}
明确声明that = this
,以便您有that.detailsUrl
的引用,然后
不要使用胖箭头作为点击处理程序,因此您可以获得正确的this
回调范围。
答案 1 :(得分:8)
您需要回退到javascript的标准方式。即将变量存储为:
var self = this;
然后,您可以使用function
代替()=>
,并使用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);
答案 2 :(得分:2)
如果您只支持拥有.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
获取它。
答案 3 :(得分:1)
我通常会在我想要的范围内将this
绑定到变量。
然而你所追随的this
可以这样找到:
constructor() {
var class_this=this;
$('.problem-detail-button').click(function (e) {
e.preventDefault();
var callback_this=e.target;
答案 4 :(得分:0)
线程的后期,但我的建议有所不同。
而不是:
var $row = $(this).closest('tr'); //this must be that of the callback
考虑使用:
var $row = $(e.currentTarget).closest('tr');
在此示例中,您可能希望在jQuery回调中使用this
的任何位置,您可以访问可以使用的函数参数。我建议使用这些参数代替this
更清晰(其中“清洁”被定义为更具表现力,并且在将来维护期间不太可能变成错误)。
答案 5 :(得分:0)
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
}
}
}
检查jquery.proxy()。 只是提醒你还有另一种方式。