I'm trying to override a native method called "localStorage" for functions INSIDE an object.
Here's a gist of what I'm trying to do:
function SomeObject(){
this.localStorage = "aaa"; //block access to localStorage for functions INSIDE this object.
... (some more code here)
_testRun(){
window.testA = localStorage; //chose to store the instance on a window (global-like) object
}
this.testRun = function(){ _testRun(); };
this.testRun2 = function(){ window.testB = localStorage;};v
}
var a = new SomeObject();
a.testRun();
a.testRun2();
(after this, when I look up window.testA and window.testB, they both point to the Native localStorage, not the custom one inside the SomeObject.)
BTW, I don't want to override a native function for the whole document.
(i.e. might use native localStorage OUTSIDE the object)
Any suggestions/solutions on how I can do this? thanks!
Try to add window.localStorage and this.localStorage instead of just localStorage
function SomeObject(){
this.localStorage = "aaa"; //block access to localStorage for functions INSIDE this object.
... (some more code here)
_testRun(){
window.testA = window.localStorage; //chose to store the instance on a window (global-like) object
}
this.testRun = function(){ _testRun(); };
this.testRun2 = function(){ window.testB = this.localStorage;};
}
Related
I want to say:
var b = new a.B();
where a is an object. I want the method B to be able to refer to the calling object a and to the newly created object b.
Normally, first reference is achieved via method context and second - via constructor context. Both contexts bind referenced objects to this keyword.
But how do I refer to both of them during a single call to B?
USE CASE:
Suppose, that I've written a library that allows user to easily insert my widget inside his web-page. Upon load my library exports a single name to the global namespace: Toolbar, which is a constructor that creates my widget within user's web-page element, called parent_dom_element:
var toolbar1 = new Toolbar(parent_dom_element);
Now, within my widget, corresponding to toolbar1 object, user can create sub-widgets like this:
var comment = new toolbar1.Comment();
I want the constructor function Comment to be able to refer to the toolbar1 object and to act as a constructor at the same time like this:
Toolbar.prototype.Comment = function (toolbar, ){
this.attr1 = toolbar.attr1;
};
How to achieve this?
You have to define a var inside Toolbar context pointing to 'this' and define the Comment constructor inside the Toolbar constructor. This way, the Comment contructor will get access to the 'toolbar' variable.
var Toolbar = function () {
var toolbar = this; // toolbar = Toolbar instance
this.attr1 = ""; // this = Toolbar instance
this.Comment = function () {
this.attr1 = toolbar.attr1; // this = Comment instance;
};
};
var toolbar1 = new Toolbar();
var comment = new toolbar1.Comment();
I want to have singleton kind of object whose value gets changed during multiple events across multiple pages. This object is used to bind the ui in various pages.
I have a 'main.js' file :
var obj = { flag : false } ;
// call back method
function click() {
obj.flag = true;
}
and in my next.js file
// call back method
function click() {
alert(obj.flag); // **alerts false** . It should alert **true** instead.
}
Is there a way to persist the value other than using the window.name property ? or am I following the wrong approach
You can use HTML5 localStorage.
As described in the documentations (Safari, Mozilla etc.), localStorage supports string key/value pairs.
Therefore you need to use JSON.stringify to save your object in the storage.
var obj = { flag : false };
// Save the object in the storage
localStorage.setItem('obj', JSON.stringify(obj));
// Get the object from storage
var objectData = localStorage.getItem('obj');
var originalObject = JSON.parse(objectData );
alert(originalObject.flag);
See the following fiddle: http://jsfiddle.net/FdhzU/
Scenario:
The MVC web page gets JSON object with lots of data. Upon click of button (there are quiet a number of buttons) I would like to reuse this JSON object and select required JSON Properties (without making a request to server).
It's not HTML5 so can't use browser local storage. At the moment I'm storing the JSON object on GLOBAL variable and reusing it.
Are there any elegant options available to store and re-use returned JSON object on client side?
Just cache the data. There is no need to store the JSON in a global variable, I'm sure you'll find a place in your MVC application to scope a local variable. You will have implemented a getter function for the data with a callback. With caching, it'll look like this:
var getData = (function(){
var cache;
var loading = false;
var callbacks = [];
return function(callback) {
if (typeof cache != "undefined")
callback(cache);
else {
callbacks.push(callback);
if (!loading) {
loading = true;
doSingleHeavyAjaxCall(options, function success(data) {
cache = data;
for (var cb; cb = callbacks.shift();)
cb(cache);
});
}
}
};
})();
Then use getData(function callback(data){...}) as often as you want, and it will only trigger one ajax request.
Another option to Jakubs answer is creating a global variable that you can update and retrieve as you like on the page.
Global variables get attached to the window object, so just write this in your <head> section.
<script type="text/javascript">
window.jsonData = {};
</script>
Then wherever you're retrieving your data just update that object.
<script type="text/javascript">
$.ajax(..., function(data) {
window.jsonData = data;
});
</script>
Then you can use it wherever you like in your code on that page.
<script type="text/javascript">
console.dir(jsonData);
</script>
You can store the object in data- attribute of some element - preferably container for the part of your page that represents your data (table, grid):
var json = {};
$('#mygrid').data('mydata', json);
You can retrieve it later
var json = $('#mygrid').data('mydata')
jQuery data() method documentation: http://api.jquery.com/data/
I'm trying to extend the functionality of some methods of the 2dcontext object, however I can't get it to work the way I want: I want to override a method, but I want to call the original method from the overridden method like this:
//First get the original context
var ctx = canvas.getContext("2d");
//Create a class which uses ctx as it's prototype
var ExtendedContext = function (){};
ExtendedContext.prototype = ctx;
//And extend a method
ExtendedContext.prototype.fillRect = function(x, y, width, height) {
//Do some stuff
this.prototype.fillRect(x, y, width, height); //Doesn't work
//Do some more stuff
};
How can I call the original fillRect method from inside my own method?
You can store the reference of the original function just like that:
var oldFillRect = ctx.fillRect;
and then call it like
ExtendedContext.prototype.fillRect = function() {
//Do some stuff
oldFillRect.apply(this, arguments);
//Do some more stuff
};
This technique is sometimes called 'duck punching' or a 'function hook'. In this particular instance, you should also be able to use the Object.getPrototypeOf method to get the original function reference. This would look like
ExtendedContext.prototype.fillRect = function() {
//Do some stuff
Object.getPrototypeOf(ExtendedContext.prototype).fillRect.apply(this, arguments);
//Do some more stuff
};
So you don't even need to store a reference.
No need to save the old names in a separate object, use closures :
ExtendedContext.prototype.fillRect = (function () {
var oldf = ExtendedContext.prototype.fillRect;
return function () {
//Do some stuff
oldf.apply (this, arguments);
//Do some more stuff
};
}) ();
If you have a bunch to do this might help :
function extend (fnc) {
var mthd = (fnc.toString ().match (/^function\s+(\w+)\s*\(/) || ['', ''])[1];
if (mthd in ExtendedContext.prototype)
throw ('ExtendContext method ' + mthd + 'does not exist');
ExtendedContext.prototype['_' + mthd] = ExtendedContext.prototype[mthd];
ExtendedContext.prototype[mthd] = fnc;
}
Then you can call extend as follows
extend (function fillrect () {
// Do some stuff
this._fillrect.apply (this, arguments);
// Do some more stuff
});
To refer to the old method use its name prefixed with '_'
I'm a few months late, but I'm using a fairly simple design to accomplish this functionality.The structure of our JavaScript runs off of a global object to keep our code secured from global vars.
For each page/usercontrol we are modifying our global object to hold a new object, but some code needs different functionality in different places, requiring extension methods. We don't want to duplicate code and redefine the whole object for the extended instance, and we don't want the code to care how it is being extended.
Instead of punching a duck until it does what you want it to, why not create a generic extension method? Using our case, here is an example:
// Using a Global JavaScript object:
GlobalNameSpace.ExtensionFunction = function(oParam1, oParam2, oParam3)
{
/// <summary>All parameters are optional</summary>
return; // For instances when it is not being overwritten, simply return
}
//In the Code to be extended:
GlobalNameSpace.Control.ControlFunction(oSender, oArgs)
{
///<summary>Control's function</summary>
// Function-y stuff..
GlobalNameSpace.ExtensionFunction(oSender, oArgs);
}
//and finally in the code to extend the functionality
GlobalNameSpace.Page.Init
{
///<summary>Initializes the page</summary>
// redefine the extension function:
GlobalNameSpace.ExtensionFunction = function(oSender, oArgs)
{
// Call the extension function, or just code the extension here
GlobalNameSpace.Page.Function(oSender, oArgs);
}
}
The short coming of this method is if you want to do this for multiple objects at a time, at which point it may be a better idea to move an extension method into the code you are specifically wanting to extend. Doing this will make that extension code less generic, but that can be decided according to your needs.
I am working on a Javascript object that contains some YUI objects. The key thing is, my object needs to contain it's own set of YUI tabs so that I can display multiple instances of my object on the same page and have the tabs control their own object instance.
I set it up as follows:
var Scheduler = function(divid,startDate,mode){
this.tabView = null;
...
this.init = function(){
this.tabView.appendTo(this.calendar_cell);
this.tabView.addTab( new YAHOO.widget.Tab({
label: 'Day',
content:'<div id="'+ this.calendar_day_div +'" style="width:100%; height:auto;"></div>'
}));
var tab0 = this.tabView.getTab(0);
tab0.addListener('click', this.showWeek);
}
this.showWeek(){
alert(this);
}
});
Here's the problem. I would expect the alert(this); in this.showWeek to alert the instance of scheduler. Instead, it's giving me the tab li. I tried alerting this.parent and am given 'undefined' as an answer.
How should I set this up to do what I need to do?
The addListenter method takes a scope argument. So you can change your call to the following to solve your problem (since you are using YUI):
tab0.addListener('click', this.showWeek, undefined, this);
When you attach a function to an event of an object (in this case the object held by tab0) then its usually that object that becomes the this context of the function when it executes.
Adjust your code like this:-
var self = this;
this.showWeek(){
alert(self);
}