存储实例以在嵌套地图/对象中使用

时间:2016-08-22 13:10:00

标签: javascript jquery

我的JQuery Widget有一个非常讨厌的范围问题。基本上我需要在我的地图/对象options内访问小部件实例(this)。

有可能这样做吗?有什么建议我可以做到这一点吗?

$.widget( "my.myWidget", {

    // Below 'this.defCallback' will be undefined
    // How can I store 'this' (the widget instance) in a variable??
    options: {
        callback: this.defCallback  // allow user to overwrite/provide custom callback
    },


    ....


    defCallback: function() {
        console.log('defCallback');
    }
});

如果我有一个嵌套函数,我知道我可以很容易地解决这个问题,但是我有一个嵌套的对象/地图会让事情变得困难。

function foo {
    var _this = this;

    ...

    var bar = function() {
        // easily access this
        _this.defCallback();

        ...
    }
}

用法:

$('<div></div>')
    .myWidget();  // use defCallback

$('<div></div>')
    .myWidget({
        callback: function() {
            ...
        }
    });  // use custom callback

编辑:回调函数如何“绑定”并调用:

    _create: function() {
        this.element.click( this.options.callback );
    }

。点击(value.callback(_this)

1 个答案:

答案 0 :(得分:1)

在javascript中,您可以使用 apply() call()方法动态更改函数的上下文。

在es5上,您可以使用 bind()

所以你的代码:

  

_create:function(){          this.element.click(this.options.callback);       }

成为 apply()

_create: function() {
    var el = this.element;
    var callback = this.options.callback;
    el.click(function() {
         callback.apply(el);
         // If you have parameters:
         // callback.apply(el, arguments || array);
    });
}

使用 call()

_create: function() {
    var el = this.element;
    var callback = this.options.callback;
    el.click(function() {
         callback.call(el);
         // If you have parameters:
         // callback.call(el, arg0, arg1, ...);
    });
}

使用 bind()

_create: function() {
    this.element.click(this.options.callback.bind(this));
}

<强>更新

由于您的问题是将引用绑定在对象定义中,因此您需要更改代码。

快速的方法是像这样(从你的小提琴)修改它:

var mw = {
    defCallback: function () {
        alert("abc");
    },
    _create: function () {
        //this.populateOptions();
        alert("Is undefined: " + this.options.isUndefined);  // outputs 'true'
        this.element.click(this.options.callback.bind(this));
    },
    populateOptions: function() {
        if (this.options.callback === undefined)
            this.options.callback = this.defCallback;
    }   
};

因此,您首先使用父属性和函数定义对象。

mw.options = {
    //accessObjectParent: this.instantiator,
    isUndefined: (mw.defCallback === undefined), // this refers to the map/object 
    // Can I access the maps 'parent'/instantiator?
    // this.instantiator.defCallback ???
    callback: mw.defCallback
};

与附加选项对象相比,您可以引用父对象而不是使用 this

$ .tidget(&#34; my.myWidget&#34;,mw);

现在你传递了小部件声明中的对象。