最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - A Backbone.js view that is a simple select list - Stack Overflow

programmeradmin1浏览0评论

I've built a Backbone-powered library that allows a user to add/remove items, much like the Todos example.

Every time an item is add or removed - or the entire collection is refreshed - I need two other select elements that are on other areas of the page to re-populate with the latest items as options. How would this be implemented, do I simply re-populate the select element in the render function of the view which holds a reference to the collection?

I'm tempted to create a view just for the select options but this seems like overkill, especially when considering the view doesn't need to re-act to any events. The select options are used by other views to populate form data.

I've built a Backbone-powered library that allows a user to add/remove items, much like the Todos example.

Every time an item is add or removed - or the entire collection is refreshed - I need two other select elements that are on other areas of the page to re-populate with the latest items as options. How would this be implemented, do I simply re-populate the select element in the render function of the view which holds a reference to the collection?

I'm tempted to create a view just for the select options but this seems like overkill, especially when considering the view doesn't need to re-act to any events. The select options are used by other views to populate form data.

Share Improve this question asked May 13, 2011 at 8:06 Matty FMatty F 3,7934 gold badges33 silver badges48 bronze badges 2
  • Where is said library? I could really use it! – George R Commented Aug 25, 2011 at 2:42
  • @GeorgeR documentcloud.github./backbone – UpTheCreek Commented Oct 20, 2011 at 16:05
Add a ment  | 

2 Answers 2

Reset to default 7

You're correct: create a unique view for each select option. It's not overkill at all; that's what Views are for. They listen for events from their models, in this case the item list, and redraw themselves upon receiving an event. They have container designations, so once you've established those in the parameters for the View subclass, you never need to think about them again. You can style them independently.

That's the whole point of the Views being the way they are.

More importantly, you could also abstract out "view of a list of things," and then each of your specific views can inherit from that view, and add two features: the filter ("latest"), and the renderer. You have to write the renderer anyway; you may as well exploit a little syntatic sugar to make it clear what you're rendering where. It's better than writing ments.

Not to distract from Elf Sternberg's already excellent answer, but to add a little context:

Don't loop over collections in your templates

If you want to do this, you might as well just use HTML partials and AJAX. Instead, use a Backbone View that renders its own views (the granularity is what minimizes server syncs and page refreshes). This is recursive, you can repeat this pattern until there is no more associated data to loop over.

— Jonathan Otto in A Conceptual Understanding of Backbone.js For The Everyman

Of course, there are a few gotchas when you want to render subviews.

I did a code search to try and find some examples of how to do this. Turns out that the TodoMVC example is a good model for doing this. From the Strider-CD source (MIT License):

var UserView = Backbone.View.extend({

    //... is a class. not sure how to put that here
    tagName: "option",

    // Cache the template function for a single item.
    template: _.template($('#user-item-template').html()),

    // The DOM events specific to an item.
    // maybe could put links here? but then user couldn't see on mouse-over

    // The UserView listens for changes to its model, re-rendering. Since there's
    // a one-to-one correspondence between a **User** and a **UserView** in this
    // app, we set a direct reference on the model for convenience.
    initialize: function() {
      _.bindAll(this, 'render');
      this.model.bind('change', this.render);
      this.model.bind('destroy', this.remove);
    },

    // Re-render the contents of the User item.
    render: function() {
      $(this.el).html(this.template(this.model.toJSON()));
      return this;
    },

    // Remove the item, destroy the model.
    clear: function() {
      this.model.clear();
    }

  });

  // The Application
  // ---------------

  // Our overall **AppView** is the top-level piece of UI.
  var UsersView = Backbone.View.extend({
    // Instead of generating a new element, bind to the existing skeleton of
    // the App already present in the HTML.
    el: $("#user-form"),

    // no events here either at this time

    // At initialization we kick things off by
    // loading list of Users from the db
    initialize: function() {
      _.bindAll(this, 'addAll', 'addOne','render');

      Users.bind('add', this.addOne);
      Users.bind('reset', this.addAll);
      Users.bind('all', this.render);

      console.log("fetching Users");
      Users.fetch();
    },

    // Re-rendering the App just means refreshing the statistics -- the rest
    // of the app doesn't change.
    render: function() {
      console.log("rendering User AppView");
      // might want to put some total stats for the Users somewhere on the page

    },

    // Add a single todo item to the list by creating a view for it, and
    // appending its element to the `<ul>`.
    addOne: function(User) {
      console.log("adding one User: " + User.get("id") + "/" + User.get("email"));
      var view = new UserView({model: User});
      this.$("#user-list").append(view.render().el);
    },

    // Add all items in the **Users** collection at once.
    addAll: function() {
      console.log("adding all Users");
      console.log(Users.length + " Users");
      Users.each(this.addOne);
    }


  });
  // Finally, we kick things off by creating the **App**.
  console.log("starting userapp now");
  var UsersApp = new UsersView();

});

Additional examples of a select list view with option sub-views can be found in:

  • Zipkin source
  • reviewboard source
发布评论

评论列表(0)

  1. 暂无评论