Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Repeating sub-views #19

Closed
searls opened this Issue Dec 12, 2011 · 10 comments

Comments

Projects
None yet
4 participants
Contributor

searls commented Dec 12, 2011

This is more an open question than an issue, since I don't see anything in the docs that adress it:

Do you (or backbone.layoutmanager) have an opinion on how to best handle repeated subviews, one for each in a collection?

Owner

tbranyen commented Dec 12, 2011

Something like a list that contains a subview of list items?

Contributor

searls commented Dec 12, 2011

Right. I've got a collection with a collection view to house some collection-wide controls and the parent elements for each item in the collection. Right now that collection view is doing the heavy lifting of instantiating each model's view, rendering it, and placing it in the DOM.

I'd love to see a way to accomplish this relatively common pattern using a more declarative layoutmanager configuration.

sontek commented Dec 28, 2011

I think this is similar to what I want to do.

I have a primary view that holds a collection. But I want to be able to manage click events on each of its models, but since I'm allowing re-ordering/deleting I can't do it based on collection index. So I want to have subviews for each model and render those out.

With standard backbone.js I would do that like this:

    render: function() {
            var ele = this.el;
            $(ele).empty();

            this.collection.each(function(user) {
                var view = new Permissions.UserView({
                    model: user,
                    collection: Permissions.users
                });

                $(ele).append(view.render().el);
            });

        return this;
    }
Contributor

searls commented Jan 4, 2012

@tbranyen any further thoughts on this? I feel like I run into a wall with layout manager as soon as my layout reaches a point where I need to render a collection view that contains one subview per model contained in the collection. I'm struggling to imagine how backbone.layoutmanager would help solve this problem short of providing its own opinionated convention of how a "collection view" ought to behave.

Just curious your thoughts on how you might approach this, regardless of whether you're interested in adding to the library.

Owner

tbranyen commented Jan 4, 2012

Yeah dude definitely have thought about it. I'm thinking its more of a custom render method

var SubView = Backbone.View.extend({
  render: function() { /* ... Some magic ... */ }
});

var RepeatingView = Backbone.View.extend({
  render: function(layout) {
    var collection = this.collection;

    return layout(this).render().then(function(el) {
      collection.each(function(model) {
        $(el).append(new SubView({ model: model }).render().el);
      });
    });
  }
});

Maybe a more clever way with LayoutManager will emerge. Especially to be able to leverage the auto-template stuff.

Contributor

searls commented Jan 5, 2012

Thanks for the reply and I'm glad to hear it's on your mind.

I'm bummed because as it stands, my current application has several layers of repeated views (say, a list of zoos have a list of animals that have a list of toys). So far I do have something like you shared above but because it breaks awareness from the overall layout to the subviews I can only use LayoutManager for the first layer of nesting (zoos); I'm back to hand-rolling a normal standalone backbone view for the animals and toys.

I've read the source code but I'm not sure how I'd go about adding collection awareness to LayoutManager, because the set of each subview type would change on the fly all the time.

Owner

tbranyen commented Jan 9, 2012

Hey @searls I've been thinking about this more and I think this might be a good solution:

The first major change that should happen is in the partial function.

// Currently
partial: function(layout, name, template) {
  $(layout).find(name).html(template);
}

// New
partial: function(layout, name, template) {
  $(layout).find(name).append(template);
}

This will allow us to call partial multiple times and append instead of replacing every single time.

Now for the front-facing implementation something like this:

// Passing 2 views
var main = new Backbone.LayoutManager({
  views: {
    ".list": [ new ItemView(), new ItemView() ]
  }
});

Lets say you're dynamically creating views through, maybe something like this:

var ItemView = Backbone.LayoutManager.View.extend({
  template: "something"
});

var ListView = Backbone.View.extend({
  render: function(layout) {
    var view = layout(this);

    this.collection.each(function(myModel) {
      // For each subView add to the main view
      view.append(new ItemView({ model: myModel }));
    });

    // Instead of using the internal el, use the one specified with partial?
    return view;
  }
});

// Passing a collection
var main = new Backbone.LayoutManager({
  views: {
    ".list": new ListView({ collection: myCollection })
  }
});

What do you think of this API?

Contributor

searls commented Jan 9, 2012

Thanks for the thoughtful reply. I'm tied up at the moment but I've made a note to come back and look at this tomorrow morning, and I'll add some thoughts then.

sontek commented Jan 9, 2012

I think this is a good API, the only thing I might add is a specific view that does all if it automatically. So rather than creating our own custom render that loops through the collection, have a LayoutManager.ListView that does all that for us?

The CollectionView and ItemView in https://github.com/derickbailey/backbone.marionette are pretty sweet

@tbranyen tbranyen closed this in b878e21 Jan 20, 2012

@staydecent staydecent referenced this issue in rotundasoftware/backbone.subviews Mar 6, 2013

Closed

Repeating subviews #1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment