Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>How the binding works is largely determined by the Rivets adapter you are using, although your model could also do the heavy lifting.</p> <h2>Option 1: Smart Model</h2> <p>If you're using <a href="http://backbonejs.org" rel="noreferrer">Backbone.js</a>, you could take a look at <a href="https://github.com/powmedia/backbone-deep-model" rel="noreferrer">backbone-deep-model</a>, which supports path syntax for nested attributes (Eg. <code>store.get('ActiveItem.Price')</code>), though it is still under development. If that doesn't quite meet your needs, there are other <em>nested model</em>-type options on the <a href="https://github.com/documentcloud/backbone/wiki/Extensions,-Plugins,-Resources" rel="noreferrer">Backbone plugins and extensions wiki</a>.</p> <h2>Option 2: Smart Adapter</h2> <p>If that doesn't work for you, you can extend your Rivets adapter to handle path syntax. I've put together a simple example on how to do this at <a href="http://jsfiddle.net/zKHYz/2/" rel="noreferrer">http://jsfiddle.net/zKHYz/2/</a> with the following naive adapter:</p> <pre><code>rivets.configure({ adapter: { subscribe: function(obj, keypath, callback) { /* Subscribe here */ }, unsubscribe: function(obj, keypath, callback) { /* Unsubscribe here */ }, read: function(obj, keypath) { var index = keypath.indexOf('.'); if (index &gt; -1) { var pathA = keypath.slice(0, index); var pathB = keypath.slice(index + 1); return obj[pathA][pathB]; } else { return obj[keypath]; } }, publish: function(obj, keypath, value) { var index = keypath.indexOf('.'); if (index &gt; -1) { var pathA = keypath.slice(0, index); var pathB = keypath.slice(index + 1); return obj[pathA][pathB] = value; } else { return obj[keypath] = value; } } } }); </code></pre> <h2>Option 3: Dirty Hacks</h2> <p>As of version 0.3.2, Rivets supports <a href="https://github.com/mikeric/rivets#iteration-binding" rel="noreferrer">iteration binding</a>. By creating a Rivets formatter that returns an array, you can "iterate" over your property. Take a look at <a href="http://jsfiddle.net/mhsXG/3/" rel="noreferrer">http://jsfiddle.net/mhsXG/3/</a> for a working example of this:</p> <pre><code>rivets.formatters.toArray = function(value) { return [value]; }; &lt;div data-each-item="store.ActiveItem | toArray &lt; store.ActiveItem""&gt; &lt;label&gt;name:&lt;/label&gt;&lt;input data-value="item.Name &lt; store.ActiveItem"/&gt; ... &lt;/div&gt; </code></pre> <p>I'm not sure if the computed property syntax is required here; you will have to test this with your model to see what works.</p> <h2>Option 4: Don't bind deeper than one level (Recommended)</h2> <p>The need to bind deeper than one level may be an indication that your design can be improved.</p> <p>In your example, you have a list of Items in an ItemCollection for a Store. You go about assigning a single Item to the Store's ActiveItem property, setting up events everywhere to try link things together, and then need to be able to bind to the properties of the ActiveItem under the Store, yet have things update whenever the ActiveItem itself changes, etc..</p> <p>A better way of doing this is by using a view-per-model approach. In your example, you're trying to handle the Store Model, the ItemCollection and the Item Model with a single view. Instead, you could have a parent Store view, a subview for the ItemCollection, and then generate Item views as necessary below that. This way, the views are easier to build and debug, less tightly coupled to your overall Model design, and are more readily reusable throughout your application. In this example, it also simplifies your Model design, as you no longer need the ActiveItem property on the Store to try maintain state; you simply bind the Item View to the selected Item Model, and everything is released with the Item View.</p> <p>If you're using <a href="http://backbonejs.org" rel="noreferrer">Backbone.js</a>, take a look at <a href="http://backbonejs.org/#View" rel="noreferrer">Backbone.View</a> as a starting point; there are many examples online, although I'll be the first to admit that things can get somewhat complex, especially when you have nested views. I have heard good things about <a href="https://github.com/tbranyen/backbone.layoutmanager" rel="noreferrer">Backbone.LayoutManager</a> and how it reduces this complexity, but have not yet had the chance to use it myself.</p> <p>I've modified your most recent example to use generated Item views at <a href="http://jsfiddle.net/EAvXT/8/" rel="noreferrer">http://jsfiddle.net/EAvXT/8/</a>, and done away with the ActiveItem property accordingly. While I haven't split the Store view from the ItemCollection view, note that I pass their Models into Rivets separately to avoid needing to bind to <code>store.Items.models</code>. Again, it is a fairly naive example, and does not handle the full View lifecycle, such as <a href="http://rivetsjs.com/#usage-notes" rel="noreferrer">unbinding Rivets</a> when the View is removed.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload