Reputation: 4668
I understand the basic idea of javascript constructor like
function Person(name){
this.name = name
}
Person.prototype.sayhi = function(){
return this.name+' says hi !!! '
}
var bob = new Person('bob')
bob.name // bob
bob.sayhi // bob says hi !!!
but lets say if i want to create a Album in real webapp, the server send an array of json data
like:[{'id':1,'album_name':'test','user':'user_id'}]
, each array item should be an album, now i want to construct this album as div element using this array item,how can i do that?
the reason why i want this is that if i can construct an album as real div element,then i can do this
Album.prototype.open = function(){
//some action
}
album = new Album(jdata)
album.click(function(){
this.open()
})
is this possible , how to define this constructor , i think this may have something to do with constructor return value which really confuse me!!!
Upvotes: 4
Views: 8050
Reputation: 1174
Create some template files with classes matching the object keys, and then cycle through the keys and populate the template file. For example:
function Album (album) {
this.template = $('#template').clone().removeAttr('id');
this.album = album;
}
Album.prototype.html = function () {
var i, val;
for (i in this.album) {
if (!this.album.hasOwnProperty(i)) {
continue;
}
val = this.album[i];
this.template.find("." + i).html(val);
}
console.log(this.template);
return this.template;
}
var foo = new Album({
title: 'Cheap Thrills',
artist: 'Frank Zappa',
genre: 'Rock and Roll'
});
$('#main').html(foo.html());
that's a one-size-fits-all attempt, though it won't really fit all needs. You can set conditions or what-have-you for cases where this solution doesn't fit your needs. For example, if the data is an image url, setting the innerHTML isn't very useful, so you would instead set the 'src' attribute, or create an img tag with an SRC attribute.
A template file might look like this:
<div class="album">
<div class="user"></div>
<span class="foo"></span>
<textarea class="bar"></textarea>
</div>
Here's a quick fiddle: http://jsfiddle.net/bxw7Z/
If you don't like the idea of using classes, try data-attributes instead.
Upvotes: 0
Reputation: 8789
You can do the following:
var i, data, Albom, albom;
Albom = function Albom(data) {
var i,
div = document.createElement('div');
for(i in data) {
div.setAttribute('data-'+i, data[i]);
}
div.innerHTML = data.album_name;
for(i in this) {
if(typeof this[i] === 'function') {
div[i] = this[i].bind(div);
} else {
div[i] = this[i];
}
}
return div;
};
Albom.prototype.open = function open() {
alert(this.getAttribute('data-id'));
};
data = [
{'id':1,'album_name':'test1','user':'user_id1'},
{'id':2,'album_name':'test2','user':'user_id2'}
];
for(i in data) {
albom = new Albom(data[i]);
document.body.appendChild(albom);
}
Now new Albom(data)
will produce new DOM element that has attributes from provided data
object and will have all prototype properties and functions inside created element that will be executed in scope of this DOM element (so you can refer to this
inside that methods).
For example you will be able to call albom.open()
and an alert with text 2
will pop-up.
Working example you can see at: http://jsbin.com/isepay/10/edit
Upvotes: 3
Reputation: 2173
I think your approach is wrong. You should render the response JSON object using any client side templating engine (For e.g. Handlebars.JS).
Then define constructor & prototype methods like
function album(container){
this.container=container
}
album.prototype.open=function() {
container.show();
}
album.prototype.renderHTML=function(jdata) {
//This is handlebar.js code
template=$('#albumTemplate').text();
compiledTemplate=Handlebars.compile(template);
renderedTemplate=compiledTemplate(jdata);
container.html(renderedTemplate);
}
Once this is done, you have album class ready & can start using it like this
var container=document.getElementById('myalbum001'),
album=new album(container);
container.on('click',function(e){
album.render(jdata); //You can get jdata by making AJAX call before this line
album.open()
}
I will recommend you to quickly take a glance at Handlebar.js
Upvotes: -2