16

我有一个非常简单的课程,但已经在 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' 含义的冲突

你如何处理“这个”的混合物?

4

6 回答 6

15
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回调的正确范围。

游乐场

于 2013-05-03T14:35:52.097 回答
9

您需要回退到 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);
于 2013-05-03T14:35:06.283 回答
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.

于 2013-05-03T14:42:44.377 回答
1

this我通常会在我想要的范围内绑定一个变量。

但是,this您可以像这样找到您所追求的:

constructor() {
    var class_this=this;
    $('.problem-detail-button').click(function (e) {
        e.preventDefault();
        var callback_this=e.target;
于 2013-05-03T14:36:23.283 回答
0

迟到了,但我有一些不同的建议。

代替:

var $row = $(this).closest('tr'); //this must be that of the callback

考虑使用:

var $row = $(e.currentTarget).closest('tr');

如本例所示,您可能希望this在 jQuery 回调中使用的任何地方,都可以访问可以使用的函数参数。我建议使用这些参数而不是this更清洁(其中“更清洁”被定义为更具表现力,并且在未来维护期间不太可能变成错误)。

于 2014-03-07T20:16:54.323 回答
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()。只是提醒你还有另一种方法。

于 2017-03-17T08:07:46.453 回答