简体   繁体   中英

Iterate over a collection of Backbone.js models using Rivets.js?

I'm using Rivets.js for two two-way data binding in a Backbone project and would like to implement iteration binding. The documentation suggests iteration binding is possible, but there are no examples available. I am using a simple Rails API to send JSON to the client and want to iterate over the contents. Has anyone had any success getting this functionality working in Rivets.js?

Reference material: Simple Example using Backbone.js and Rivets.js

jsFiddle here: http://jsfiddle.net/rhodee/3qcYQ/1/

From the Rivets.js site

Iteration Binding

Even though a binding routine for each-item will likely be included in Rivets.js, you can use the data-html binding along with a set of formatters in the interim to do sorting and iterative rendering of collections (amongst other cool things).

 <ul data-html="model.tags | sort | tagList"></ul> 

Expanding on this answer:

As of 0.3.2 there is now a data-each-[item] binding for exactly this purpose.

Note that you will need to specifically modify your Rivets adapter to work with a Backbone Collection, as the out-of-the-box examples on the Rivets.js site do not fly with this use case.

You'll need something like this in your rivets.configure({ adapter: ... }) :

...
read: function( obj, keypath ) {
    return obj instanceof Backbone.Collection 
       ? obj["models"] 
       : obj.get(keypath)
}

And the JS Fiddle: http://jsfiddle.net/tigertim719/fwhuf/70/

For bonus points, Collections embedded in Models will require additional handling in your adapter.

For more information, check this post on Rivets.js Github issues:
Binding to Backbone.Collection with the data-each- binding

As of 0.3.2 there is now a data-each-[item] binding for exactly this purpose.

<ul>
  <li data-each-todo="list.todos">
    <input type="checkbox" data-checked="todo.done">
    <span data-text="todo.summary"></span>
  </li>
<ul>

For previous versions of Rivets.js, the work-around that you've referred to is to implement the iterative rendering with a formatter — for example you would have a data-html binding with model.items | itemList model.items | itemList where the itemList formatter just loops over the array and returns some rendered HTML.

rivets.formatters.itemList = (array) ->
  ("<li>#{item.name}</li>" for item in array).join ''

UnderscoreJS is integrated in Backbone so you can use its native methods like _.each() or use the integrated Backbone Collection underscore methods .

Is it this what you are looking for?

cayuu's answer was correct. But the rivets.js reference in the fiddle was not working, so the result is not displaying.

Check out the version below to see the action.

http://jsfiddle.net/tigertim719/fwhuf/70/

rivets.configure({
  adapter: {
    subscribe: function(obj, keypath, callback) {
      obj.on('change:' + keypath, callback);
    },
    unsubscribe: function(obj, keypath, callback) {
      obj.off('change:' + keypath, callback);
    },
    read: function(obj, keypath) {
        return obj instanceof Backbone.Collection ? obj["models"] : obj.get(keypath);
    },
    publish: function(obj, keypath, value) {
      obj.set(keypath, value);
    }
  }
});

The most important part is

read: function(obj, keypath) {
            return obj instanceof Backbone.Collection ? obj["models"] : obj.get(keypath);
        },

That tells rivets how to read your collection and model from Backbone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM