Reputation: 828
Resolved!! see the end of the question for the result that I used
I am trying to write a function that can handle my apps paging by routes.
I have a function route() that is called with argument being the route(page) to move to.
route is an object that defines a model that it uses that handles its logic. This model contains 3 functions indexAction - This renders my view and appends it to my page. bindEvents - This is where I have placed all of my click events shutDown - This is instructions to run when moving to a new page
The router function first runs shutdown on the current page, here I have the $(selector).off() and $(selector).remove()
it then runs the enidexAction and bindEvents function.
My issue now is when I return to this page, all my click functions are running twice, then three times etc... its as if the off() never actually unbind from the anchor.
here is an example of one of my models
var NewPageModel = (function() {
var instance;
var modal = 'null';
function createInstance() {
var object = {
indexAction: indexAction,
shutDown: shutDown,
bindEvents: bindEvents
};
return object;
}
function indexAction (data, callback){
var partials = {};
ViewManager.render('pageName',{context:data}, partials,function(html){
ViewManager.appendUnique('#xxx',html,'uniqueID');
callback();
});
}
/**
* Remove modal
*/
function shutDown(){
this.modal.off();
this.modal.remove();
}
function bindEvents() {
if(this.modal!='null'){
return;
}
this.modal = $(PagerManager.pages.newGroup.id);
this.modal.on('click','div.close', function () {
shutDown();
});
this.modal.on('click', 'button.cancel', function () {
shutDown();
});
this.modal.on('click', 'button.submit', function () {
//code that submits form information
});
}
return {
getInstance: function () {
if (!this.instance) {
this.instance = createInstance();
}
return this.instance;
}
};
})();
EDIT!! So I am still learning about the importance of scopes and how they can be applied to functions Here is the working code var NewPageModel = (function() { var instance; var modal; function createInstance() { var object = { indexAction: indexAction, shutDown: shutDown, bindEvents: bindEvents }; return object; }
function indexAction (data, callback){
var partials = {};
ViewManager.render('pageName',{context:data}, partials,function(html){
ViewManager.appendUnique('#xxx',html,'uniqueID');
callback();
});
}
/**
* Remove modal
*/
function shutDown(){
this.modal.off();
this.modal.remove();
this.modal = null;
}
function bindEvents() {
//This is confused logic, if I use off() in shutdown, I don't need to do this as I need to bind all the events again. hence in shutdown modal=null;
if(!this.modal){
return;
}
this.modal = $('#modal');
this.modal.on('click','div.close', function () {
shutDown().apply(this);
}).bind(this);;
this.modal.on('click', 'button.cancel', function () {
shutDown().apply(this);
}).bind(this);;
this.modal.on('click', 'button.submit', function () {
//here I only use the apply(this) if I use another internal function
//code that submits form information
}).bind(this);;
}
return {
getInstance: function () {
if (!this.instance) {
this.instance = createInstance();
}
return this.instance;
}
};
})();
Upvotes: 0
Views: 156
Reputation: 77966
In the spirit of keeping your syntax and just fixing the bug,
if(this.modal!='null'){
should be if(modal!='null'){
Because this.modal
will be undefined
at that condition and will just return.
In the spirit of fixing your code, you need to keep a reference to this
or it will default to window
in the browser.
var modal;
function createInstance() {
var object = {
modal : modal,
shutDown: shutDown,
bindEvents: bindEvents
};
return object;
}
function bindEvents() {
if(this.modal){
return;
}
// ..... //
this.modal.on('click','div.close', function () {
shutDown.apply(this);
}.bind(this));
// ..... //
}
Working demo :
Upvotes: 1
Reputation: 93561
You are losing your this
in the event handler functions (this
will be the element clicked) so the shutDown
is not getting the correct this
:
this.modal.on('click','div.close', function () {
shutDown();
});
should be:
var self = this;
this.modal.on('click', 'button.cancel', function () {
self.shutDown();
});
e.g.
function bindEvents() {
var self = this;
if(this.modal!='null'){ /// <<<< !!!!!! WTF
return;
}
this.modal = $(PagerManager.pages.newGroup.id);
this.modal.on('click','div.close', function () {
self.shutDown();
});
this.modal.on('click', 'button.cancel', function () {
self.shutDown();
});
this.modal.on('click', 'button.submit', function () {
//code that submits form information
});
}
Note: I am ignoring the string comparison to null
for now as I have no clue what you are doing there :)
As pointed out in comment by @Gurami Dagundaridze
you can also retain the correct this
using bind
(I think the syntax goes like this):
this.modal.on('click', 'button.cancel', shutDown.bind(this));
Upvotes: 2