0

I'd like to create a collection of objects that works like an array. Some time ago, I made this question and I came up with the following solution with the help of the people that helped me:

Newobj.Collection = function(){
    Array.apply(this);

    for(var i = 0; i < arguments.length; i++){
        for(var j = 0; j < arguments[i].length; j++){
            this.push(arguments[i][j]);
        }
    }

    return this
}

Newobj.Collection.prototype = Object.create(Array.prototype);
Newobj.Collection.prototype.push = function(o){
    Array.prototype.push.call(this, new Newobj.Element(o));
}

However, this leaves the children unconnected from the parent. For example, imagine this collection has a render() function, which makes its children to print some HTML onto the page. Well, I'd like to be able to say something like:

Newobj.Collection.html_container = '#cont';

Newobj.Collection.render = function(){
    $.each(this, function(i, el){
        el.render()
    })
}

Newobj.Element.render = function(){
    $(parent.html_container).html('.......')
}

It should be able to set different collections in one page, so make a global container for all the Newobj.Collections is not a solution. This is an example, and I need this for more complex processes than just a render() function.

Anyone has an idea how can I make an array to be able to access a parent class which it is part of?

If the solution could be JSON.stringifyed and be seen as an array on the server side, it would be great too, though it's not the main problem for this question. Right now, if I set a property to the array, it is seen as an object with size > 0 on the server side.

Thank you!

Community
  • 1
  • 1
Unapedra
  • 2,043
  • 4
  • 25
  • 42

1 Answers1

1

Create reference to collection in element:

Newobj.Collection.prototype.push = function(o){
  Array.prototype.push.call(this, new Newobj.Element(o,this));
}

//element constructor gets as second paramater instance of collection
Newobj.Element=function(o,collection){

  //this.parent in every element is collection reference
  this.parent=collection;
}


Newobj.Element.prototype.render = function(){
   $(this.parent.html_container).html('.......')
}

or no reference in Element option:

Newobj.Collection.render = function(){

  var parent=this;

  $.each(this, function(i, el){
    el.render(parent.html_container)
  })
}

Newobj.Element.render = function(html_container){
  $(html_container).html('.......')
}

But this version need to have methods parameters.

Maciej Sikora
  • 19,374
  • 4
  • 49
  • 50
  • Hadn't thought of that. I'll test it and when I see if it works (that it should, as I read it) I mark your answer as the correct one! Thank you for your help! – Unapedra Jul 25 '16 at 15:10
  • I've come up with a *performance* possible problem. If I put the *collection* as a parameter, what will happen to the element number 100 when I get there? Will it have a property called *parent* in which there are 99 other elements already? and the 99th, will have a *parent* property with an array with 98 elements, and so on? – Unapedra Jul 25 '16 at 15:57
  • This paramater is object reference so it will be no 100 objects but one object and 100 references, so it will be no performance problems. – Maciej Sikora Jul 25 '16 at 16:07
  • As it is an object (or it should), it is passed by reference, but I don't know if this will still affect performance on operations such as `JSON.stringify()`, where it will encode the whole parent array. EDIT (we wrote at he same time): ok. I will check! Thank you! – Unapedra Jul 25 '16 at 16:07
  • I am getting an `Uncaught TypeError: Converting circular structure to JSON` because of the reference... Do you know any way I can do it without having to implement my own serialisation method? – Unapedra Jul 25 '16 at 16:13
  • Thank you! I'll mark the answer as correct because I think these are the most correct methods to use! I will think wether to use one or another. Thank you again for your help! – Unapedra Jul 25 '16 at 16:16