1
votes

I'm trying to build an app where there is a CompositeView that handles mouse events, allowing you to draw rectangles inside it(the CompositeView is a collection of rectangles). I'm calculating/storing all the needed data for a rectangle (basically width, height, top, left and border css properties) inside the CompositeView.

Since I'm calculating stuff, I've used the itemViewOptions function, that returns an object with all data necessary, that will be passed as options to my ItemView (RectangleView).

In the initialize method of the ItemView I call the setCssStyle method, that applies the css properties to the view.

Here's my CompositeView (ScreenView) and ItemView (RectangleView) code (calculations and data-stopring methods ommited for brevity)

var RectangleView = Backbone.Marionette.ItemView.extend({
  template: "<div>I am a rectangle</div>",
  className: "rectangle",

  initialize: function(options){
    this.left = options.left;
    this.top = options.top;
    this.width = options.width;
    this.height = options.height;
    this.border = options.border;
    this.setCssStyle();
  },
  setCssStyle: function () {
    this.$el.css({
      'width': this.width + 'px',
      'height': this.height + 'px',
      'top': this.top + 'px',
      'left': this.left + 'px',
      'border': this.border
    });
  }
});


var ScreenView = Backbone.Marionette.CompositeView.extend({
  template: "<div>  </div>",
  className:"screen",
  itemView: RectangleView,

  itemViewOptions: function() {
    return {
      left: this.left,
      top: this.top,
      width: this.width,
      height: this.height,
      border: this.border
    }
  },

[...]

});

I've read that I need to override the buildItemView method passing it 3 parameters: item, ItemViewType, itemViewOptions according to the Marionette Documentation

Th problem is that I'm a bit confused and I don't really know what is the item parameter I'm supposed to pass. Is it the model for the ItemView? I tried different stuff and kept getting errors, so chances are I'm missing something fundamental here.

Also, currently I don't have a model for my RectangleView. Should I create one, and how can I pass the itemViewOptions from my CompositeView to my ItemView and eventually to the model?

I apologize in advance if I didn't explain my issue well, but my brain feels kinda mushy

1

1 Answers

1
votes

Ok I managed to figure this out on my own, I guess I needed some slep to clear my head! I don't know if it's an optimal solution, but it works for me.

First of all, I've switched from a CompositeView to a CollectionView since I don't need recursiveness. I've also created an empty Rectanglemodel and a Rectangles collection.

In my App.Initializer when I show the CollectionView I also pass the rectangles collection to it! .show(new ScreenView({collection: rectangles}));

Now, as you might remember, the whole deal was being able to draw rectangles inside the CollectionView, the rectangles drawn within the CollectionView would be added in a collection (each would have a model etc etc...)

The ideal place to put that code was on my mouseup event inside my CollectionView (think about it, you click--> drag-->release the mouse button to draw a box)

[...]
  handleMouseUp: function(e) {
    [...]
    if (this.dragging===1) {

      //passing the itemViewOptions on a helper
      var modelHelper = this.itemViewOptions();

      //instantiating Rectangle by passing it the itemViewOptions
      var rectangle = new Rectangle (modelHelper);

      //adding newly instantiated rectangle in the collection
      this.collection.add(rectangle);
      console.log(this.collection);
    }
  },

As soon as you add the rectangle in the collection, the CollectionView will take care of rendering it! :)

Please let me know if there could be any optimizations or other ways of doing this! Now I have to take care of the css properties because my rectangles won't render in place :/