Imnl
Imnl

Reputation: 456

CompositeView and Waiting images to be loaded

I have implemented a marionette region that draws columns depending on the screen size, so i have variable number of columns. The problem that i have is that i want to locate the itemView in the column with the smallest height. But the CompositeView appendHtml method seems to append all itemViews before a i can calculate correctly the height of the column. The ItemView has a image and is not rendered yet,so im not calculating correctly the height.

I paste my aproximation:

  appendHtml: (collectionView, itemView, index) ->
    $("#column-container").waitForImages ->
      smallest_column = 0
      columns= $("#column-container").children().length
      column_sizes = []
      for i in [0...columns]
        column_sizes[i] = $($("#column-container").children()[i]).height()

      smallest_column = column_sizes.indexOf(Math.min.apply(Math,column_sizes))
      target = $($("#column-container").children()[smallest_column])
      target.append(itemView.el)

I have watched that this method appends all the collection items and this could be one reason to do this logic in other place.

PD: I dont want to use masonry.

Upvotes: 0

Views: 64

Answers (1)

Mark Stratmann
Mark Stratmann

Reputation: 1612

I have tried to deal with this a number of ways, the most practical I have found is to simply set a timer that fires lets say every half second to set the height of columns that I what to control.

So for instance If I have a number of columns and I all want them to be the same height (the height of the tallest) then I would do something like this.

Here is a small module that I use for this in my views:

define([
'jquery',
'underscore'
],
function($, _){
var tools =  {
  makeColHeightSame: function(col_array, min_height) {
    var max_col_height = 0;
    _.each(col_array, function(col, index, cols){
      $(col).removeAttr('style');
      var height = $(col).height();
      if (height > max_col_height) {
        max_col_height = height;
      }
    }, this);

    _.each(col_array, function(col, index, cols){
      if (_.isUndefined(min_height)) {
        $(col).height(max_col_height);
      } else {
        if (max_col_height < min_height) {
          $(col).height(min_height);
        } else {
          $(col).height(max_col_height);
        }
      }
    }, this);
  }
};

return tools;

});

I my view I do the following:

      initialize: function(){
       // Set up resize timer
       this.resize_timer = setInterval(_.bind(this.resizeCols, this), 500);
     }

When the view is destroyed:

  onBeforeDestroy: function() {
    clearInterval(this.resize_timer);
  },

And my Resize Cols function is:

  resizeCols: function() {
    ViewTools.makeColHeightSame(this.$('.registration_box_bottom'));
    ViewTools.makeColHeightSame(this.$('.opportunities_block'));
  },

I am using underscore.js to make sure that the this context is set to my view when the timer fires and the using require.js to bring in the ViewTools module.

Upvotes: 1

Related Questions