Variable Scope: cross-class function call - javascript

I have a vehicle and a product object and I need vehicle to call a function within product.... I can't seem to figure it out, what should I do here?
var vehicle = function () {
return {
init: function () {
var that = this;
jQuery('.vehicle-year-profile .options .delete').bind('click', function (e) {
e.preventDefault();
that.remove(jQuery(e.currentTarget).parents('.vehicle-year-profile'));
});
jQuery('.vehicle-year-profile .options .edit').bind('click', function (e) {
e.preventDefault();
that.edit(jQuery(e.currentTarget).parents('.vehicle-year-profile').attr('id'));
});
jQuery('#association-detail .save').bind('click', function (e) {
e.preventDefault();
that.save();
});
},
edit: function (id) {},
save: function () {},
remove: function (el) {},
reset: function () {}
}
}();
var product = function () {
return {
refreshHistory: function () {}
};
}();

Have you tried
product.refreshHistory();
?? The variable "product" is global (or at least relatively global), so code inside the "vehicle" object can refer to it directly.

Related

Calling a private/nested javascript function from an outer scope

I have my javascript code like this . Inside that I have an init() function and in that function I have an options JSON object and in that object I have a function defined as objectselected(). How I call that function in a button click event
I have tried like this WorkFlow.init().options.Objectselected() but it is not working,
var WorkFlow = {
connectionData: [],
selectedTouchpoints: [],
init: function () {
var options = {
palleteId: "myPaletteElement",
elementId: "playAreaContainer",
TextStoreList: ['One', 'Two', 'Three'],
LinkTextStoreList: $('#drpLinkType option').map(function () {
return this.text;
}).get(),
shapeList: ['RoundedRectangle', 'Circle', 'Rectangle', 'Ellipse', 'Square', 'Diamond', 'Card', 'Database'],
diagramUpdate: function (e) {
},
objectSelected: function (e) {
},
linkUpdate: function (e) {
},
initialize: function () {
}
myGraph = new Graph(options);
options.initialize();
},
}
How to call that function.
One way around is you can return options and than call it.
init: function () {
var options = {
...your code..}
return options;
},
and call it than
var options = WorkFlow.init();
options.Objectselected();
As it stands, you have no access to options because it's a local variable - that is, local to its scope.
To access its contents, you'll need to return it from init().
Think about it:
WorkFlow.init()
Currently this returns undefined, because your init() returns nothing. You're trying to chain like in jQuery, but that relies on the API always returning the instance. Your path finds a dead-end at init().
To fix this, have init() return options - or at least the part of it you want to access from outside - an "export".
So (basic example)
init: function() {
var options {
my_func: function() { }, //<-- we want outside access to this
private: 'blah' //<-- this can stay private - leave it out of the export
}
//return an export, exposing only what we need to
return {
my_func: options.my_func
}
}
You need to return options as it is inside init function's scope
var WorkFlow = {
connectionData: [],
selectedTouchpoints: [],
init: function () {
var options = {
palleteId: "myPaletteElement",
elementId: "playAreaContainer",
TextStoreList: ['One', 'Two', 'Three'],
LinkTextStoreList: $('#drpLinkType option').map(function () {
return this.text;
}).get(),
shapeList: ['RoundedRectangle', 'Circle', 'Rectangle', 'Ellipse', 'Square', 'Diamond', 'Card', 'Database'],
diagramUpdate: function (e) {
},
objectSelected: function (e) {
},
linkUpdate: function (e) {
},
initialize: function () {
}
myGraph = new Graph(options);
options.initialize();
return options;
},
}
And call it as WorkFlow.init().objectSelected();
Building on Patrick's comment, you'd need to return options from the init function:
var WorkFlow = {
connectionData: [],
selectedTouchpoints: [],
init: function () {
var options = {
palleteId: "myPaletteElement",
...
options.initialize();
return options;
},
}

Javascript wrong binding: function disappear but variables ok

The problem is that when I am binding this to function in .then() of Promise all variables is binded but 1 which is function, not.
define([
'Service/service',
'core/widget'], function (service, widget) {
return widget.extend({
init: function (options) {
this.options = options;
console.log('this.options: ', this.options); //{actionToDo:function(),variables...}
service.getFile('app/Core/Widgets/Button/Views/button.html')
.then(
function(){
console.log('this.options: ', this.options); //{actionToDo:undefined,...}
}.bind(this)
)
}
});});
I am creating the object by:
new Button(
{
elementToAppend: this.className + ' .actions > .actionButtons',
class: action.class,
icon: action.icon,
text: action.text,
unique: action.unique,
actionToDo: function(){//some code}
}
);
And the widget:
define(['underscore'], function (_) {
function Widget() {
}
return {
extend: function (methods) {
var widget = new Widget();
widget.prototype = {
trigger: function (event) {
switch (event) {
case 'click':
{
this.onClick.call(this);
break;
}
}
}
};
var Widget_Extended = _.extend(widget.prototype, methods);
return function (options) {
Widget_Extended.init(options);
return Widget_Extended;
};
}
};});
Could you tell me why inside function in .then() 1 parametr of options is undefined?
The solve of the problem (I guess) is:
define(['underscore'], function (_) {
function Widget() {
}
return {
extend: function (methods) {
return function (options) {
var widget = new function () {
};
widget.prototype = {
trigger: function (event) {
switch (event) {
case 'click':
{
this.onClick.call(this);
break;
}
}
}
};
var Widget_Extended = _.extend(widget.prototype, methods);
Widget_Extended.init(options);
return Widget_Extended;
};
}
};});

JS scope: call parent function using namespace

How do I call a parent namespace function from within a function?
var myNamespace = {
funcOne : function () {
//do something
},
funcTwo : function () {
setTimeout ( function () {
myNamespace.funcOne(); //how do I call funcOne?
}, 2000);
}
}
The usual way would be to use the this keyword inside the literal
var myNamespace = {
funcOne : function () {
//do something
},
funcTwo : function () {
var self = this;
setTimeout ( function () {
self.funcOne();
}, 2000);
}
}
But what you're doing should work just fine as well -> FIDDLE

Trouble with Jquery widget

I have a widget like this
$.widget("ui.myWidget", {
//default options
options: {
myOptions: "test"
},
_create: function () {
this.self = $(this.element[0]);
this.self.find("thead th").click(function () {
this.self._headerClick(); //how do I do this!!!
});
this.self._somethingElse();
},
_headerClick: function (){
},
_somethingElse: function (){
},
.
.
.
The line this.self._headerClick(); throws an error. This is because in that context this is the th element that was clicked. How do I get a reference to the _headerClick function?
Store the scope of desired this within a variable.
$.widget("ui.myWidget", {
//default options
options: {
myOptions: "test"
},
_create: function () {
var that = this; // that will be accessible to .click(...
this.self = $(this.element[0]);
this.self.find("thead th").click(function () {
that._headerClick(); //how do I do this!!!
});
this.self._somethingElse();
},
_headerClick: function (){
},
_somethingElse: function (){
},
Untested, but maybe something like this:
_create: function () {
var self = this,
$elem = $(self.element[0]);
$elem.find("thead th").click(function() {
self._headerClick();
});
self._somethingElse();
},

Javascript variable scope

Is it possible for me to call selectCompanyJump(this) internally without calling it from App.site.profile?
Instead of doing App.site.profile.selectStateJump(this); can I do like parent.selectStateJump(this); without reassigning this outside of the .change() call?
$(document).ready(function () {
App.site = function () {
return {
init: function () {
this.profile.init();
},
profile: function () {
var profile;
return {
init: function () {
profile = $('div#profile');
$('select[name="company_id"]', profile).change(function () {
App.site.profile.selectCompanyJump(this);
});
$('select[name="state_id"]', profile).change(function () {
App.site.profile.selectStateJump(this);
});
},
selectCompanyJump: function (select) {
$(select.parent()).submit();
},
selectStateJump: function (select) {
$(select.parent()).submit();
}
}
}()
}
}();
App.site.init();
});
You can reference the "this" scope you want as another variable outside change() function definitions:
profile: function () {
var profile;
return {
init: function () {
profile = $('div#profile');
var self = this;
$('select[name="company_id"]', profile).change(function () {
self.selectCompanyJump(this);
});
$('select[name="state_id"]', profile).change(function () {
self.selectStateJump(this);
});
},
selectCompanyJump: function (select) {
$(select.parent()).submit();
},
selectStateJump: function (select) {
$(select.parent()).submit();
}
}
}()
Assuming that you are just using the select argument of your functions to reference the element that triggered the event you could just pass a pointer to the event binder and then use the this keyword.
profile: function () {
var profile;
return {
init: function () {
profile = $('div#profile');
$('name="state_id"', profile).change(this.selectStateJump);
},
selectStateJump: function () {
$(this).parent().submit();
}
}
you can do the following
$(document).ready(function () {
App.site = function () {
var me = this;
me.selectStateJump = function selectStateJump (select) {
$(select.parent()).submit();
}
return {
....
selectStateJump: selectStateJump
}
and you'll be able to call just me.selectStateJump()
EDIT:
actually below would be enough
$(document).ready(function () {
App.site = function () {
function selectStateJump (select) {
$(select.parent()).submit();
}
return {
method : function(select) {
selectStateJump(select);
}
selectStateJump: selectStateJump
}

Categories