获取父类属性

时间:2012-11-16 16:31:38

标签: javascript jquery

我有一个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)
                    );
                });
            }
        });
    }
}

2 个答案:

答案 0 :(得分:2)

parent()用于DOM遍历。你所拥有的是一个范围问题。

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

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

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)
                    );
                });
            }
        });
    }
}

通过这种方式,您可以在实例内的任何位置访问任何实例的公共方法和属性。

PS。根据惯例,Instanceables / Constructors通常首字母大写。

答案 1 :(得分:1)

在异步Ajax调用之前捕获this

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

您似乎期望this有两个含义

  1. 当您使用$(this).parent()...时,您希望this成为某些HTMLDOMElement
  2. 当您使用this.name时,您希望this成为data(可能是数组)中的对象项。
  3. 获取对象实例引用的解决方案

    很明显,COMPANYPage是你的类(应该是Pascal套装而不是驼峰套装)。因此在this内使用。{1}}。您可能通过以下方式创建它:

    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)
                    );
                });
            }
        });
    };