Reputation:
In my company we have a survey framework to help stakeholders create surveys, I'm trying to create a re-usable object which will allow a team member to easily set the width of a particular question for a survey - they can sometimes be a bit squished depending on the length of the answers. I'm trying to use a combination of the module and constructor pattern but not sure if I pulled it off correctly. Is there a better way to write my code?
var WidthIncreaser = (function(){
return function (element, words, width) {
var element = $(element);
var re = new RegExp(words, 'gi');
return {
init: function() {
if (element.text().match(re)) {
element.width(width);
}
}
};
};
})();
var tr = new WidthIncreaser('td.choicev-question:first', 'Applicable from the', 400);
tr.init();
The idea is, somebody can create a new instance of WidthIncreaser and pass in an element, a string which matches the question's text so it's the right question being targeted and the size to set width of the question to.
Thanks for the advice in advance!
Upvotes: 2
Views: 434
Reputation: 25322
I don't think you actually need "the module pattern" here. You can just take advantages of closures and that's all:
function WidthIncreaser(element, words, width) {
element = $(element);
var re = new RegExp(words, 'gi');
this.init = function () {
if (element.text().match(re)) {
element.width(width);
}
}
}
var tr = new WidthIncreaser('td.choicev-question:first', 'Applicable from the', 400);
tr.init();
Of course you don't need necessary init
in that case, because you could put everything in the ctor, but I assume it's just an example and maybe you need lazy initialization.
In that way you can keep your prototype
chains, and you statements like:
tr instanceof WidthIncreaser // true
will works.
In addition, you can also populate the prototype
with methods that doesn't need to access to the scoped variables, at least not directly:
WidthIncreaser.prototype.doSomething = function() { /* .. */ }
For instance, if you can't use getter and setter because cross browsing restriction, you could have a function like that:
function WidthIncreaser(element, words, width) {
element = $(element);
var re = new RegExp(words, 'gi');
this.element = function() { return element };
this.init = function () {
if (element.text().match(re)) {
element.width(width);
}
}
}
WidthIncreaser.prototype.reset = function () {
this.element().text("")
}
So basically you can retrieve the element from outside, but it's read-only, the WidthIncreaser
can set elements only during the instantiation.
Edit: I copied and pasted init
that of course it didn't work for a dependency with re
, so it was a bad example to illustrate the approach.
Upvotes: 0
Reputation: 46647
The module pattern I use usually looks like this:
var myModule = (function () {
var myPrivateVar = 'foo';
var myPrivateFunc = function () {
console.log('bar');
};
return {
myPublicFunc: function () {
console.log(myPrivateVar);
}
};
}) ();
Then it would be used like this:
myModule.myPublicFunc();
Upvotes: 0
Reputation: 119837
You are double wrapping stuff. Anyways, the common module pattern I see is just a function that returns an object with closure.
No need for the new
keyword nor an immediate function. Immediate functions are usually used when only one object is made and assigned directly to one variable. In your case, you wanted to make "instances".
var WidthIncreaser = function(element, words, width) {
var element = $(element),
re = new RegExp(words, 'gi');
return {
init: function() {
if (element.text().match(re)) {
element.width(width);
}
}
};
};
var tr = WidthIncreaser('td.choicev-question:first', 'Applicable from the', 400);
tr.init();
Upvotes: 1