Passing arguments to init in ember.js - javascript

How can I pass arguments to init() or access the arguments passed to create() inside init() in ember.js

Just use this.get('theProperty')
Example:
var data = {
foo: "hello",
};
var MyModel = Em.Object.extend({
init: function() {
this._super();
var foo = this.get('foo');
alert(foo);
}
});
MyModel.create(data);

Use closures and create a new init function that passes the closed argument to its prototype init function. Also, this way you don't end up overwriting sensitive properties, like methods for example.
note: init is called after all the properties are set by the constructor
Class = Ember.Object.extend({
init:function(response){
console.log(this.get("msg")+this.get("msg_addressee")+"?");
console.log(response);
},
msg:"SUP, "
});
var arg = "not much.";
obj = Class.create({
init:function(){
console.log("output:");
this._super(arg);
console.log("indeed, "+arg);
},
msg_addressee:"dude"
});
//output:
//SUP, dude?
//not much.
//indeed, not much.

Related

Javascript OOP use function inside object

I have JS object
var widget = {
check_balance: function(){...},
function_called_in_init: function(){
.....
this.check_balance();
};
};
this is code screenshot for better understanding..
and when it try to call this.check_balance(); it returns me error TypeError: this.check_balanceis not a function
the question would be - how to call function inside object which was also created inside object?
Also I can't init this function at the moment when all object is inited, becouse this is a recursion with ajax callback.
Its a little tricky to see what you are asking but the gist of it is you are looking to have the correct context. The tool for that is the whatever.bind(theContext) function. You pass in theContext to the object and that makes theContext object the context of whatever.
var parent = {
foo: function () {
var widget = {
check_balance: function(){ console.log('checking'); },
function_called_in_init: function(){
this.bar();
}.bind(this),
};
widget.function_called_in_init();
},
bar: function () {
console.log('bar');
},
};
parent.foo();
see fiddle
bind documentation
Use private function and closure
var widget = (function() {
var check_balance = function() {
//do what your check_balance has to do
}
return {
check_balance: check_balance,
function_called_in_init: function(){
.....
check_balance();
};
};
})();

Prototype js super method call or something like this

Prototype js allows to call super method by $super. I need call class-method from object, but in overriden method, like this:
var ClassA = Class.Create({
initialize: function(options) {
Object.extend(this, options);
},
method1: function(){/*some code*/}
});
var ClassB = Class.Create(ClassA, {
method1: function($super) {
$super(); // this works fine, calls ClassA.method1()
}
});
var objectA = new ClassA({
method1: function($super) { // I need something like this
$super(); // this not works, must calls ClassA.method1()
}
});
How can I do this?
If you want just objectA to have the new method, do this:
var objectA = new ClassA();
objectA.method1 = objectA.method1.wrap(function (fn) {
fn(); // works like a `$super` call inside of a class
});
It uses Function#wrap to add advice around the function.
If you need to pass arguments to the function, do this:
var objectA = new ClassA();
objectA.method1 = objectA.method1.wrap(function () {
var args = $A(arguments), fn = args.shift();
fn(args); // works like a `$super` call inside of a class
});
If you want to redefine the method in an already defined Class you need to use Class#addMethods
var ClassA = Class.Create({
initialize: function(options) {
Object.extend(this, options);
},
method1: function(){/*some code*/}
});
ClassA.addMethods({
method1: function() {
/** does something else **/
}
});
However this will overwrite the method1 method and not create a subclass or child method of the original one
http://api.prototypejs.org/language/Class/prototype/addMethods/
For my needs I find next decision:
function singleton() {
var AnonymousClass = Class.create.apply(Class, arguments);
return new AnonymousClass();
}
This function get me chance to override any method in class.
Example
singleton(ClassA, {
method1: function($super) {
/* call of $super() */
}
})
This work for me as I wanted. Function returns for me object with overrided method from class, but this method can calls $super.

Object doesn't inherit parent object functions

I have some functions defined inside an object:
var functions = {
__construct: function(){
console.log(this);
this.prototype.__construct(); // <problem
}
};
I merge this object with another one that is a function (after I create a new instance of the function):
var plugin = function(){};
plugin.prototype.__construct = function(){
console.log('parent');
};
var i = new plugin();
i = $.extend({}, i, functions);
But after that when I try to call the __construct function:
i.__construct();
I get this error:
Uncaught TypeError: Cannot call method '__construct' of undefined
It's because this line:
this.prototype.__construct();
I tried to see if I can call the parent constructor function from the child constructor, but it appears that the object doesn't have a prototype? wtf?
Not sure what you're trying to do here but i does have a __construct function when using the code you provided:
var functions = {
__construct: function(){
console.log(this);
this.prototype.__construct(); // <problem
}
};
var plugin = function(){};
plugin.prototype.__construct = function(){
console.log('parent');
};
var i = new plugin();
i = $.extend({}, i, functions);
console.log(i.__construct===functions.__construct);//true
console.log(i.__construct===plugin.prototype.__construct);//false
Not sure what you think this.prototype is going to be, maybe this answer will clear up what prototype is used for (shared members) and what this means (instance specific). You can shadow shared members that are defined in the prototype further down the prototype chain or in an instance but that's not what you're doing here.
If you dynamically want to extend an instance created with a constructor function you can do something like this:
var functions = {
__construct: function(){
this.constructor.prototype.__construct.call(this);
}
};
var Plugin = function(){};
Plugin.prototype.__construct = function(){
console.log('parent');
};
var i = new Plugin();
i = $.extend(i,functions);
i.__construct();

Call function from string inside object?

I have a function name in a string:
var func = "doTest";
I need this function to be applied to the current instance ("this");
So I need it to call:
this.doTest();
How can I do this? I cannot go via window.
Thanks,
Wesley
Just use the construct of object[functionName]();, like so:
function Person() {};
Person.prototype.speak = function() { alert('ohai'); };
var john = new Person, action = 'speak';
john[action]();
Alternative style:
var Person = {
speak: function() { alert('ohai'); },
speakDelegate: function() { var action = 'speak'; this[action](); }
};
Person.speakDelegate();
this[func]();
No need to .call or .apply since context is held in the reference.
For example:
var obj = {
doTest: function(){ console.log(this); },
fn: function(){ var name='doTest'; this[name](); }
};
obj.fn(); // logs the object, proving this has the correct context.
Try the following
var funcObj = this["doTest"];
funcObj.apply(this);
What this does is grab the member named doTest from this. It then executes the function via apply and tells javascript to bind this as this within the function. I think the example is a bit less confusing if you consider the same code on a non-this value
var obj = {
doTest: function() {
console.log("doTest called");
}
};
var doTestFunc = obj["doTest"];
doTestFunc.apply(obj);
In this case the method doTest will be executed with the value obj as this
If you are using jquery you can just do:
$(this)[func]()

Is it possible to append functions to a JS class that have access to the class's private variables?

I have an existing class I need to convert so I can append functions like my_class.prototype.my_funcs.afucntion = function(){ alert(private_var);} after the main object definition. What's the best/easiest method for converting an existing class to use this method? Currently I have a JavaScript object constructed like this:
var my_class = function (){
var private_var = '';
var private_int = 0
var private_var2 = '';
[...]
var private_func1 = function(id) {
return document.getElementById(id);
};
var private_func2 = function(id) {
alert(id);
};
return{
public_func1: function(){
},
my_funcs: {
do_this: function{
},
do_that: function(){
}
}
}
}();
Unfortunately, currently, I need to dynamically add functions and methods to this object with PHP based on user selected settings, there could be no functions added or 50. This is making adding features very complicated because to add a my_class.my_funcs.afunction(); function, I have to add a PHP call inside the JS file so it can access the private variables, and it just makes everything so messy.
I want to be able to use the prototype method so I can clean out all of the PHP calls inside the main JS file.
Try declaring your "Class" like this:
var MyClass = function () {
// Private variables and functions
var privateVar = '',
privateNum = 0,
privateVar2 = '',
privateFn = function (arg) {
return arg + privateNum;
};
// Public variables and functions
this.publicVar = '';
this.publicNum = 0;
this.publicVar2 = '';
this.publicFn = function () {
return 'foo';
};
this.publicObject = {
'property': 'value',
'fn': function () {
return 'bar';
}
};
};
You can augment this object by adding properties to its prototype (but they won't be accessible unless you create an instance of this class)
MyClass.prototype.aFunction = function (arg1, arg2) {
return arg1 + arg2 + this.publicNum;
// Has access to public members of the current instance
};
Helpful?
Edit: Make sure you create an instance of MyClass or nothing will work properly.
// Correct
var instance = new MyClass();
instance.publicFn(); //-> 'foo'
// Incorrect
MyClass.publicFn(); //-> TypeError
Okay, so the way you're constructing a class is different than what I usually do, but I was able to get the below working:
var my_class = function() {
var fn = function() {
this.do_this = function() { alert("do this"); }
this.do_that = function() { alert("do that"); }
}
return {
public_func1: function() { alert("public func1"); },
fn: fn,
my_funcs: new fn()
}
}
var instance = new my_class();
instance.fn.prototype.do_something_else = function() {
alert("doing something else");
}
instance.my_funcs.do_something_else();
As to what's happening [Edited]:
I changed your my_funcs object to a private method 'fn'
I passed a reference to it to a similar name 'fn' in the return object instance so that you can prototype it.
I made my_funcs an instance of the private member fn so that it will be able to execute all of the fn methods
Hope it helps, - Kevin
Maybe I'm missing what it is you're trying to do, but can't you just assign the prototype to the instance once you create it? So, first create your prototype object:
proto = function(){
var proto_func = function() {
return 'new proto func';
};
return {proto_func: proto_func};
}();
Then use it:
instance = new my_class();
instance.prototype = proto;
alert(instance.prototype.proto_func());

Categories

Resources