2016-08-22 35 views
2

我的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)

+0

你還可以顯示調用'callback'函數的代碼嗎? – Tomalak

回答

1

在JavaScript中,你可以動態地改變一個函數的上下文與apply()調用()方法。

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

所以,你的代碼:

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

成了申請()

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

隨着呼叫()

_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, ...); 
    }); 
} 

隨着綁定()

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

UPDATE

由於您的問題是有引用你需要改變你的代碼的對象定義裏面綁定。

快速的方法是就是訂正像這樣(從你的提琴):

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

比你附加選項對象,你可以參考父對象上,而不是使用這個的。

$ .widget(「my.myWidget」,mw);

現在你在你的小部件聲明中傳遞該對象。

+0

不起作用,問題在於存儲'this.options'內的函數引用。看到這個JSFiddle:https://jsfiddle.net/va4ge5as/4/ –