Examples of multiple instance javascript widgets (on same page)? - javascript

Apologies for the quick question, but I'd like to see some sample widgets that allow multiple instances in the same page. (Articles about this technique would also be good!)
Digg's widget allows this (http://about.digg.com/downloads/widgets) but I don't know of any others.
Do you?
Thanks.

See any of the YUI widgets. Eg multiple YUI-enhanced buttons on a page.
Creating multiple instances with per-instance data
The basic technique is shown below.
Since the calling program uses new, a new instance of the Larry.widget object is created for each widget. So each widget has its own, separate object "this" and uses it for storing per-instance data.
At the same time, the object's prototype holds the functions. So all of the widgets share the same functions, but have their set of data.
Larry = {}; // Create global var
Larry.widget = function (options) {
// create with new. Eg foo = new Larry.widget({an_option: true, id: "q_el"});
// options: object with members:
// an_option
// id
// Then call foo.xyz(); to get the widget to do xyz
this.init(options);
};
Larry.widget.prototype = {
constructor: Larry.widget,
// Setting the constructor explicitly since we're setting the entire
// prototype object.
// See http://stackoverflow.com/questions/541204/prototype-and-constructor-object-properties/541268#541268
init: function(options) {
this.id = options.id;
this.an_option= options.an_option;
this._function_a(); // finish initialization via a function.
}, // remember that function init is a member of the object, so separate
// the functions using commas
_function_a: function() {
// This is a "private" function since it starts with _
// Has access to "this" and its members (functions and vars)
....
},
xyz: function() {
// This is a "public" function.
// Has access to "this" and its members (functions and vars)
...
} // Note: NO TRAILING COMMA!
// IE will choke if you include the trailing comma.
}

Related

I want access of a property of my class in a static metod, how can i do? is it possible? [duplicate]

I have a code like that:
User = function(){}
User.a = function(){
return "try";
}
User.b = function(){
}
​
From User.b() I can call User.a() using:
User.b = function(){
return User.a();
}
but not using this since it's not an instance of user (User.a() and User.b() are something like "static methods").
What i want to do is to be able to call User.a() from User.b() without knowing which is the main function, in this case User.
Something like this to be used in static methods.
In reality there is no methods or static methods in js, there's just functions that are assigned to object properties (functions being objects as well) and they all work the same way. Since you are calling it like User.b(), this will be User for the call.
User.b = function() {
return this.a();
}
The only thing that determines the context of the function is how you call it.
If you call it using a plain identifier (a function name, a variable or a property), the context will be the global window object:
someFunction();
If you call it using a period to access an object member, the context will be the object:
someObject.someFunction();
If you copy a member from an object to a variable, there is no connection to the object any more, and it will be called with window as context:
var x = someObject.someFunction;
x();
If you assign a function as a property to an object, and call it using the object, the context will be the object:
someObject.x = someFunction;
someObject.x();
For your specific case, User is a function, which also is an object.
If you call the function using User.b, its context will be the User object, which happens to be a function in this case. From within the function you can still use this to access the context:
User.b = function(){
return this.a();
}
You don't have normal inheritance in javascript. I guess you are trying to do something like this:
User = function(){
this.a= function(){
return 'try';
}
this.b= function(){
return this.a();
}
}
This way User becomes a constructor. Each new instance of User will have acces to these methods. So if you want to create a new instance of the User class, you can use the new keyword:
var client= new User()
and then you'll have access to all the methods from user using client
client.b() //returns 'try'
Well, functions exist independently of their container objects; they're just values. So if you're not calling them as methods on an object, they inherit whatever this is in the calling context. In that case, expecting them to know about their container would be the same as assigning User.x the value 1 and then expecting the number 1 to somehow know about User.
However, when you call User.a() or User.b(), you are in fact calling them as methods - methods of the (function object) User. So this will be the same as User, and b can just call this.a() and you should be good to go.

Get method's instance owner

Given a class and an instance of it
var class=function() {
this.propA=99;
this.methodA=function() {
console.log(this.propA);
};
};
var object=new Class();
I'd like to be able to perform a call to methodA where this will be the instance of it and the example (this.propA) will work. Exactly as
object.methodA.call(object);
but without having any reference to object. Like this in some pseoducode:
var methodToCall=object.methodA;
...
...
methodToCall.call(getInstanceOwnerOf(methodToCall));
The objective of this is to pass methods as callbacks to async functions and keep this as the instance when the method is called.
Some workarounds would be to pass method and object to that async function, or to store this in a local variable, but these are the things I want to avoid.
Use bind to bind to the context you want function called in. Note this returns a NEW function which is not the same as the original.
I usually create the new function and give it a different name but you can do it multiple ways.
To be more specific, you can't be sure this is the class the function is declared in, depends on how you called the function and if you are in strict mode.
an example below:
Fiddle: https://jsfiddle.net/f7af535L/
class SomeClass {
constructor(someVar) {
this.myVar = someVar;
this.publicSayVar = this.sayVar.bind(this);
}
sayVar() {
console.log(this.myVar);
}
}
var object = new SomeClass("hello");
var testcall = object.publicSayVar;
testcall();

javascript pattern used in angular

I followed a AngularJS tutorial on http://www.tutorialspoint.com/angularjs/angularjs_services.htm
The method passed to CalcService service got me confused. Is Angular using revealing prototype or a different one. I was confused because that inner function declared in this.square should be private and not visible outside the context of the object. How Angular is able to access square.
mainApp.service('CalcService', function(MathService){
this.square = function(a) {
return MathService.multiply(a,a);
}
});
An AngularJS service is a very distinct thing.
When it's initialized, it gets newed. Take this as an example:
function CalcService() {
this.square = function() {
// square some stuff
};
}
// then in the controller, directive, or wherever,
// it gets initialized behind the scenes like this
new CalcService();
However, it gets initialized as singleton, meaning that there's only ever one reference to the object, even if the component where you register it attempts to re-initialize it (see my recent answer on singletons in AngularJS).
Not sure what you mean when you mention a "revealing prototype pattern", but the this , in the case of an AngularJS service, is simply implementing a non-prototypal method on a new, regular JavaScript object.
Keeping with the same example above, in "normal" JavaScript, you could call new CalcService().square(). JavaScript doesn't have any native notion of private methods (though there are ways of implementing "class" methods that appear to be private.)
var service = new CalcService();
service.square();
There's nothing "private" about that method, just like there's nothing "private" about methods that are attached to AngularJS service objects... The only thing remotely "private" about it is that it happens to belong only to that specific object by virtue of the this keyword.
In your example, you are passing a constructor function into the angular service DI method.
In the constructor function you assign a method to this.square .
Just try this without angular and you will see you it behaves thr same.
function Calc() {
this.square = function() {
console.log('we get here');
}
}
var calc = new Calc();
calc.square();
This is the main feature of Javascript's prototype object oriented model. This is plain old OO javascript.
Above answers does good explanation how service work but they don't explained how this which is newly created object is exposed.
Whenever you create a service angular create a new object of that function for you, and that's get return whenever its get inject in controller, directive, service, etc. Internally method uses prototype of function to create an this which is context of function. Lets look at below code how it work internally.
function CalcService(){
//The line below this creates an obj object.
//obj = Object.create(CalcService.prototype)
//this = obj;
//`this` is nothing but an instance of function/CalcService.prototype which is giving access to its property attached to this
var privateVariableExample = 'test'; //this is private variable of service.
this.square = function(a) {
//return multiplacation result from here
}
//return this;
}
var objectOfCalcService = new CalcService();
objectOfCalcService.square(1);

Scope issue inside objects that are inside objects

I've come across a problem while trying to build a simple jQuery plugin, having to do with scopes I guess.
The problem in short: A class (A) creates an object (B), in which a property (C) is set to one of the class methods (D). How can I access class A's methods not contained inside the object (B) through the property ( C)?
Longer version (code below): I'm declaring an object (lets call it publicMethods) inside the plugin, comprised of a bunch of methods. These methods should be some default methods (declared inside the plugin), or user declared ones if the user has declared her own when initializing the plugin.
The idea is that when the user defines her own custom method, there should be some functions and variables accessible to her (like this.someVar) in that function.
This creates some limitations though.
I want the default methods to have access to some internal functions and variables, not contained inside the object publicMethods. But when I access these methods through the object they are inside, instead of calling them directly, I do not have access to another variables/functions not inside that object.
I'm trying to find a way to let the default methods have access to it's class siblings. I know I can do some conditional statements before calling the method (if it is user defined or not), or even declare a global variable pointing to "this", but I'd rather keep it clean.
var Plugin = function (opt) {
this.settings = $.extend({
"someVar" : "Value",
"someFunc" : null
});
this.anotherVar = "Hello World";
this.setPublic();
this.run();
}
Plugin.prototype = {
setPublic: function() {
this.publicMethods.someFunc = this.someFunc;
if ($.isFunction(this.settings.someFunc)) {
this.publicMethods.someFunc = this.settings.someFunc;
} else {
this.publicMethods.someFunc = this.someFunc;
}
},
someFunc: function(arg) {
return this.anotherVar; // returns type error the second time
},
run: function () {
this.someFunc();
this.publicMethods.someFunc();
}
}
From MDN: Function.prototype.bind():
The bind() method creates a new function that, when called, has its this keyword set to the provided value, [...].
So the following should work:
setPublic: function() {
this.publicMethods.someFunc = this.someFunc.bind(this);
if ($.isFunction(this.settings.someFunc)) {
this.publicMethods.someFunc = this.settings.someFunc.bind(this);
}
// This is redundant anyway:
/* else {
this.publicMethods.someFunc = this.someFunc.bind(this);
}*/
},

Issue related to declaring Variable in Famo.Us

I have Small application in Famo.us Framewok.
I want to declare array variable that can be use in calling js.
I have 2 .js file: (1) PageView.js (2) GetContent.js
(1) PageView.js
function AddContent() {
View.apply(this, arguments);
var getContent = new GetContent();
getContent.AddPages();
(2)GetContent.js
function GetContent() {
View.apply(this, arguments);
}
GetContent.prototype = Object.create(View.prototype);
GetContent.prototype.constructor = GetContent;
GetContent.DEFAULT_OPTIONS = {};
GetContent.prototype.AddPages = function () {
GetData();
}
I want to declare array variable in GetContent.js file that can be accessible in PageView.js using the object of GetContent defiened in PageView.js in above code.
so that i can use like getContent.variablename[1]
how to achieve it?
Your GetContent class would need to have an array assigned to it's instance like so:
this.variablename[1, 2, 3];
Adding this allows your array to be attached to the class's specific instance. Otherwise, your array will only exist for the lifetime of the function scope you create it in.
You may also find that you can't access the getContent object after it's been created in your PageView for the same reason. Instead try this.getContent = new GetContent();
Lastly, try to avoid directly accessing other class's variables directly. Instead, use getter/setter methods which allow the class to share and modify their data securely.

Categories