I would like to know what are the common approach to make this concept works:
function Abc () {
var beforeMethod = function (e) {
console.log(e);
};
this.before('bob ana', beforeMethod);
}
Abc.prototype.ana = function () { console.log('ana'); }
Abc.prototype.bob = function () { console.log('bob'); }
Abc.prototype.maria = function () { console.log('maria'); }
//
var abc = new Abc();
abc.ana();
It's supposed to call beforeMethod before bob or ana is called.
Quickly :
need to be tested and securised, but i think it do the trick !
I haven't understood what your e mean so i put the called method name in it !
var el = document.getElementById('debug');
var $l = function(val) {
console.log(val);
el.innerHTML = el.innerHTML + '<div>' + val + '</div>';
};
//___________________________________________________________________
var Before = function( methods , func , context){
methods.split(' ').map(function(m){
var ori = context[m];
if(ori){
context[m] = function(){
func.call(context , m);
return ori.apply(context , arguments);
};
}
});
};
var Abc = function () {
var beforeMethod = function (e) {
$l('from beforeMethod : ' + e);
};
Before('bob ana ', beforeMethod , this);
};
Abc.prototype.ana = function () { $l('from ana '); };
Abc.prototype.bob = function () { $l('from bob '); };
Abc.prototype.maria = function () { $l('from maria '); };
var abc = new Abc();
abc.ana();
abc.maria();
abc.bob();
<div id='debug'>Debug
<div>
I think the way to do this is to save the old prototype function in a property.
function Abc() {
this.oldana = this.prototype.ana;
this.oldbob = this.prototype.bob;
this.prototype.ana = function(e) {
console.log(e);
this.oldana();
}
this.prototype.bob = function(e) {
console.log(e);
this.oldbob();
}
}
Related
How to call the function when click on button. I created the button and print (hello on console). It will print but when I define the function for simple addition of two number then it gives error.
I used the following code:
var FormCustomControllerMixin = {
init: function (parent, model, renderer, params) {
this.importEnabled = params.importEnabled;
},
_getLocation : function(){
var a=10;
var b=20;
var c= a+b;
console.log(c);
},
_bindImport: function () {
if (!this.$buttons) {
return;
}
var self = this;
this.$buttons.on('click', '.o_button_custom_form', function () {
console.log('Hello');
a=self._getLocation();
console.log(a);
});
}
};
Hello is print but addition is not perform.
Have you tried like this?
a=_getLocation();
I gotted the solution getlocation function does not work inside FormCustomCOntrollerMixin.
var a = function getLocation () {
var a=10;
var b=20;
var c= a+b;
console.log(c);
return
}
var FormCustomControllerMixin = {
init: function (parent, model, renderer, params) {
this.importEnabled = params.importEnabled;
}
},
_bindImport: function () {
if (!this.$buttons) {
return;
}
var self = this;
debugger;
this.$buttons.on('click', '.o_button_custom_form', function () {
var b = a();
});
}
};
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 6 years ago.
I have class below when I call printData I get this.collection is undefined.
How do I access this.collection from the prototype inside printData()? Or do i need to change the class structure. Actually the object returns function which intern returns object in hierarchy.
Thanks in advance!
Sample Class:
var DbProvider = (function () {
function DbProvider(db) {
var that = this; // create a reference to "this" object
that.collection = db;
}
DbProvider.prototype.create = function () {
return {
action: function () {
var y = {
printData: function () {
alert('Hello ' + this.collection.Name);
}
};
return y;
}
};
};
return DbProvider;
})();
Usage:
var a = new DbProvider({ "Name": "John" });
a.create().action().printData();
You could save the this reference and bind it to the printData function
var DbProvider = (function () {
function DbProvider(db) {
var that = this; // create a reference to "this" object
that.collection = db;
}
DbProvider.prototype.create = function () {
var self = this;
return {
action: function () {
var y = {
printData: function () {
alert('Hello ' + this.collection.Name);
}.bind(self)
};
return y;
}
};
};
return DbProvider;
})();
var a = new DbProvider({ "Name": "John" });
a.create().action().printData();
Or you could refactor a bit and move that to the outer scope of DbProvider and use that in printData
var DbProvider = (function () {
var that;
function DbProvider(db) {
that = this; // create a reference to "this" object
that.collection = db;
}
DbProvider.prototype.create = function () {
return {
action: function () {
var y = {
printData: function () {
alert('Hello ' + that.collection.Name);
}
};
return y;
}
};
};
return DbProvider;
})();
var a = new DbProvider({ "Name": "John" });
a.create().action().printData();
just need to keep track of the this pointer correctly, like this
var DbProvider = (function() {
function DbProvider(db) {
this.collection = db;
}
DbProvider.prototype.create = function() {
var self = this;
return {
action: function() {
var y = {
printData: function() {
alert('Hello ' + self.collection.Name);
}
};
return y;
}
};
};
return DbProvider;
})();
let dbProvider = new DbProvider({
Name: "test"
});
dbProvider.create().action().printData();
Keeping ES5 syntax and the call structure a solution would be:
var DbProvider = (function () {
function DbProvider(db) {
var that = this; // create a reference to "this" object
that.collection = db;
}
DbProvider.prototype.create = function () {
var that = this;
return {
action: function() {
var y = {
printData: function () {
console.log('Hello ' + that.collection.Name);
}
};
return y;
}
};
};
return DbProvider;
})();
Definitely not elegant but it works :)
If you do not want to change your structure, you can achieve this behavior if you change you functions to arrow functions.
var DbProvider = (function () {
function DbProvider(db) {
var that = this; // create a reference to "this" object
that.collection = db;
}
DbProvider.prototype.create = function() {
return {
action: () => {
var y = {
printData: () => {
alert('Hello ' + this.collection.Name);
}
};
return y;
}
};
};
return DbProvider;
})();
The way you are creating this "class" is definitely non standard. Let me know if you want an example of how to better structure it.
I have an HTML file and this contain JavaScript code and works fine, but when I decided put the JS code in different file and call from the HTML file, doesn't work. Why?
The JS code is like this:
(function (document) {
var toggleDocumentationMenu = function () {
var navBtn = document.querySelector('.main-nav1');
var navList = document.querySelector('.main-nav2');
var navIsOpenedClass = 'nav-is-opened';
var navListIsOpened = false;
navBtn.addEventListener('click', function (event) {
event.preventDefault();
if (!navListIsOpened) {
addClass(navList, navIsOpenedClass);
navListIsOpened = true;
} else {
removeClass(navList, navIsOpenedClass);
navListIsOpened = false;
}
});
};
var toggleMainNav = function () {
var documentationItem = document.querySelector('.main-nav3');
var documentationLink = document.querySelector('.main-nav3 > .main-sub-nav');
var documentationIsOpenedClass = 'subnav-is-opened';
var documentationIsOpened = false;
if (documentationLink) {
documentationLink.addEventListener('click', function (event) {
event.preventDefault();
if (!documentationIsOpened) {
documentationIsOpened = true;
addClass(documentationItem, documentationIsOpenedClass);
} else {
documentationIsOpened = false;
removeClass(documentationItem, documentationIsOpenedClass);
}
});
}
};
var isTouch = function () {
return ('ontouchstart' in window) ||
window.DocumentTouch && document instanceof DocumentTouch;
};
var addClass = function (element, className) {
if (!element) {
return;
}
element.className = element.className.replace(/\s+$/gi, '') + ' ' + className;
};
var removeClass = function (element, className) {
if (!element) {
return;
}
element.className = element.className.replace(className, '');
};
toggleDocumentationMenu();
toggleMainNav();
})(document);
I read it's possible that works if I put like this:
$(document).ready(function() {
// the javascript code here
});
But it still doesn't working.
Now I wonder, It's possible this code works fine in separate file?
In the following function, my objects inside floatShareBar function is undefined. Do I have to init or define a var before the functions? it throws me js error : .float - function undefined.
(function($) {
.
.
.
$("body").on("ab.snap", function(event) {
if (event.snapPoint >= 768) {
floatShareBar.float()
} else {
floatShareBar.unfloat();
}
});
var floatShareBar = function() {
var fShareBar = $('#article-share');
this.float = function() {
console.log(
};
this.unfloat = function() {
console.log("unfloat");
};
};
.
.
.
})(jQuery);
You need to get an instance of that function with a self instantiating call:
var floatShareBar = (function() {
var fShareBar = $('#article-share');
this.float = function() {
console.log('float');
};
this.unfloat = function() {
console.log("unfloat");
};
return this;
})();
UPDATE 1: I modified it to create an object within the function to attach those functions to, since in the previous example this refers to the window object
var floatShareBar = (function() {
var fShareBar = $('#article-share');
var instance = {};
instance.float = function() {
console.log('float');
};
instance.unfloat = function() {
console.log("unfloat");
};
return instance;
})();
UPDATE 2: You can actually just use the new keyword as well, look here for more info
var floatShareBar = new (function() {
var fShareBar = $('#article-share');
this.float = function() {
console.log('float');
};
this.unfloat = function() {
console.log("unfloat");
};
})();
Change you function to this:
$("body").on("ab.snap", function(event) {
if (event.snapPoint >= 768) {
(new floatShareBar()).float()
} else {
(new floatShareBar()).unfloat();
}
});
function floatShareBar () {
var fShareBar = $('#article-share');
this.float = function() {
console.log(
};
this.unfloat = function() {
console.log("unfloat");
};
};
you should declare functions when using var before you call them.
I have a simple JS object which emulates traffic lights:
function TrafficLight(redTime, yellowTime, greenTime) {
var self = this;
this.__timer = null;
this.__state = null;
this.__redTime = redTime;
this.__yellowTime = yellowTime;
this.__greenTime = greenTime;
var setnewtimer = function (delay, func) {
console.log('SET!');
if (self.__timer) {
clearTimeout(this.__timer);
}
self.__timer = setTimeout(delay, func);
};
TrafficLight.prototype.toRed = function () {
this.__state = 'red';
setnewtimer(this.__redTime, function () {
console.log('RED!');
self.toGreen();
});
};
TrafficLight.prototype.toGreen = function () {
this.__state = 'green';
setnewtimer(this.__greenTime, function () {
console.log('GREEN');
self.toYellow();
});
};
TrafficLight.prototype.toYellow = function () {
this.__state = 'yellow';
setnewtimer(this.__yellowTime, function () {
console.log('YELLOW');
self.toRed();
});
};
TrafficLight.prototype.state = function () {
return this.__state;
};
this.toGreen();
}
But when I make a TrafficLight object (like var a = new TrafficLight(1000, 1000, 1000);), every a.state() call returns green (so traffic light doesn't change its state by timer. What's wrong with my code?
You don't call setTimeout correctly.
Change
setTimeout(delay, func);
to
setTimeout(func, delay);