admin管理员组

文章数量:1022743

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!!!

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!!!

Share Improve this question asked Mar 21, 2013 at 8:04 paynestrikepaynestrike 4,66814 gold badges49 silver badges71 bronze badges 4
  • There is actually a Person.constructor = function(){} available. – Jared Farrish Commented Mar 21, 2013 at 8:05
  • 1 @JaredFarrish accessing or changing a constructor of a constructor is not particularly useful. – John Dvorak Commented Mar 21, 2013 at 8:08
  • Which constructor of a constructor are you referring? – Jared Farrish Commented Mar 21, 2013 at 8:09
  • While in some browsers DOM elements implement prototype inheritance, some browsers do not implement any kind of inheritance. It isn't required by any specification so you shouldn't expect them to. See What’s wrong with extending the DOM. – RobG Commented Mar 21, 2013 at 9:38
Add a ment  | 

3 Answers 3

Reset to default 3

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./isepay/10/edit

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/bxw7Z/

If you don't like the idea of using classes, try data-attributes instead.

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();
 piledTemplate=Handlebars.pile(template);
 renderedTemplate=piledTemplate(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 remend you to quickly take a glance at Handlebar.js

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!!!

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!!!

Share Improve this question asked Mar 21, 2013 at 8:04 paynestrikepaynestrike 4,66814 gold badges49 silver badges71 bronze badges 4
  • There is actually a Person.constructor = function(){} available. – Jared Farrish Commented Mar 21, 2013 at 8:05
  • 1 @JaredFarrish accessing or changing a constructor of a constructor is not particularly useful. – John Dvorak Commented Mar 21, 2013 at 8:08
  • Which constructor of a constructor are you referring? – Jared Farrish Commented Mar 21, 2013 at 8:09
  • While in some browsers DOM elements implement prototype inheritance, some browsers do not implement any kind of inheritance. It isn't required by any specification so you shouldn't expect them to. See What’s wrong with extending the DOM. – RobG Commented Mar 21, 2013 at 9:38
Add a ment  | 

3 Answers 3

Reset to default 3

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./isepay/10/edit

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/bxw7Z/

If you don't like the idea of using classes, try data-attributes instead.

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();
 piledTemplate=Handlebars.pile(template);
 renderedTemplate=piledTemplate(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 remend you to quickly take a glance at Handlebar.js

本文标签: how to create a html element using javascript constructorStack Overflow