1

我有一个 javascript 类,它有一个使用 jQuery 发送 Ajax 请求并处理响应的方法。

我遇到的问题是我无法弄清楚如何从 jQuery 函数中获取初始父类的属性。我已经尝试过$(this).parent(),但是由于某种原因这并没有得到我需要的东西。

我的代码如下。谁能告诉我如何从这个循环中到达基类?

function companiesPage()
{
    this.childCategoriesSelectid = '#childCategoryid';

    this.setChildCategories = function()
    {
        $.ajax({
            url: this.url,
            dataType: 'json',
            success: function(data)
            {
                $.each(data.childCategories, function()
                {
                    $($(this).parent().childCategoriesSelectid)//problem here
                    .append(
                        $('<option></option>')
                        .attr('value', this.childCategoryid)
                        .text(this.name)
                    );
                });
            }
        });
    }
}
4

2 回答 2

2

parent()用于 DOM 遍历。您所拥有的是范围界定问题。

进入新函数范围时,this关键字并不总是引用同一个对象。使用 jQuery 的方法时就是这种情况,该.each()方法将设置this为被迭代的对象/元素。

看起来您正在使用构造函数实例模式,因此您只需this通过 var 声明存储对关键字引用的原始对象(实例)的引用。此引用在作用域链中将保持不变:

function companiesPage()
{
    var _this = this; //stores a reference to this instance object
    this.childCategoriesSelectid = '#childCategoryid';

    this.setChildCategories = function()
    {
        $.ajax({
            url: this.url,
            dataType: 'json',
            success: function(data)
            {
                $.each(data.childCategories, function()
                {
                    $(_this.childCategoriesSelectid) //NO problem here :)
                    .append(
                        $('<option></option>')
                        .val(this.childCategoryid)
                        .text(this.name)
                    );
                });
            }
        });
    }
}

这样,您将能够在实例内部的任何位置访问实例的任何公共方法和属性。

附言。按照惯例,Instanceables/Constructors 通常首字母大写。

于 2012-11-16T16:36:40.597 回答
1

this在异步 Ajax 调用之前捕获

Ajax 成功处理程序是异步执行的,因此会丢失其被调用者上下文(或范围)。您必须捕获this自由变量并在函数闭包中使用捕获的变量。

看来您期望this有两个含义

  1. 当你使用时,$(this).parent()...你期望this成为一些HTMLDOMElement
  2. 当您使用时,this.name您期望成为(可能的数组)this中的对象项。data

获取对象实例引用的解决方案

很明显,companyPage 是您的类(应该是 Pascal 大小写而不是骆驼大小写)。因此使用thisinside。您可能通过以下方式创建它:

var obj = new CompaniesPage();
obj.setChildCategories();

您的代码应如下所示:

var CompaniesPage = function()
{
    // keep this as public object property
    this.childCategoriesSelectId = "#childCategoryid";

    // keep this as public object method
    this.setChildCategories = function() {
        // private reference to object instance for later reuse
        var me = this;
        $.ajax({
            url: this.url, // not sure where this one's coming from
            dataType: 'json',
            success: function(data) {
                $.each(data.childCategories, function() {
                    $(me.childCategoriesSelectId).append(
                        $('<option></option>')
                            .attr('value', this.childCategoryid)
                            .text(this.name)
                    );
                });
            }
        });
    }
};

对您的课程进行额外优化

您还必须意识到,您定义类级方法的方式不是内存效率高,因为各个对象实例不会共享相同的方法,而是希望每个实例都有自己的方法,这会反映内存资源,尤其是当您创建同一类的多个实例。

这是您的课程的优化版本:

var CompaniesPage = function() {
    // keep this as public object property
    this.childCategoriesSelectId = "#childCategoryid";
}

CompaniesPage.prototype.setChildCategories = function() {
    // private reference to me as object instance
    var me = this;

    $.ajax({
        url: this.url, // not sure where this one's coming from
        dataType: 'json',
        success: function(data) {
            $.each(data.childCategories, function() {
                $(me.childCategoriesSelectId).append(
                    $('<option></option>')
                        .attr('value', this.childCategoryid)
                        .text(this.name)
                );
            });
        }
    });
};
于 2012-11-16T16:34:35.923 回答