Search code examples
javascriptarrayscollectionsparentchildren

Javascript - Collection of objects with parent properties in common


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!


Solution

  • 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.