backbone.marionette icon indicating copy to clipboard operation
backbone.marionette copied to clipboard

Region: $el set in constructor might be resolved wrongly

Open ardi-n opened this issue 7 years ago • 6 comments

Description

  1. Having a server-generated html structure of a collection I want to initialize it using a CollectionView with any needed nested views.
  2. Because child views are identical they have identical region definitions.
  3. Regions are initialized before el/$el are resolved for a view.
  4. Thus region's $el is resolved wrongly in constructor - parentEl is not yet defined so region's $el is being searched in a whole document resulting in a jQuery collection of as many elements as there are in a list.
  5. I can't use region's $el to i.e. search within it for existing html that should be initialized with nested views.
  6. Naturally region's $el is fixed after show() is called.

Expected behavior

Region's $el should be usable if it is set in constructor. Regions could be initialized after a view calls setElement.

Environment

  1. Marionette version: 3.3.1
  2. Backbone version: 1.3.3

ardi-n avatar Jun 20 '17 14:06 ardi-n

I'm pretty sure I follow this, but a fiddle would help.

This would require regions be setup after initialize as well.

Personally I think that the ideal fix would be for regions to never be initialized unless getRegion is called, so they wouldn't be in the constructor at all.

Then I also think that we should remove the DOM lookup from the region altogether. I think ideally the view should pass the el to the region rather than the whole parentEl business.

We might be able to make the getRegion a lazy evaluation without being breaking.

paulfalgout avatar Jun 20 '17 14:06 paulfalgout

A pretty poor work around for the moment would be to:

regions() {
   this.setElement(this.el);

  return {
    region: '.selector'
  }
}

paulfalgout avatar Jun 20 '17 14:06 paulfalgout

I'll try to deliver a fiddle tomorrow. But this workaround should indeed work.

ardi-n avatar Jun 20 '17 19:06 ardi-n

Here's a demo: https://jsfiddle.net/9732v9cx/ The suggested workaround does not work. Only if you call _ensureElement() on a region its $el is fixed.

ardi-n avatar Jun 21 '17 14:06 ardi-n

ah the problem in the workaround is that this.el isn't set until the backbone.view constructor call.. well actually not until the setElement call :-) in this case.. but if you change it to this.getOption('el') it should work.

paulfalgout avatar Jun 21 '17 15:06 paulfalgout

Personally I think that the ideal fix would be for regions to never be initialized unless getRegion is called, so they wouldn't be in the constructor at all.

@paulfalgout that's kind of what I did in my autoregion plugin, and indeed that's way better https://github.com/JSteunou/marionette.autoregion

JSteunou avatar Jun 22 '17 08:06 JSteunou