Skip to content
New issue

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

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow lists directive to iterate over object properties #24

Closed
ryanramage opened this issue Apr 19, 2013 · 5 comments
Closed

Allow lists directive to iterate over object properties #24

ryanramage opened this issue Apr 19, 2013 · 5 comments

Comments

@ryanramage
Copy link
Contributor

This idea is born out of using ractive for about a day. So feel free to shoot it down in flames.

Once challenge I have noticed is managing large lists. When updates/deletes come in, one has to find the row in an array that matches the update so one can view.set('row[0]', update).

One idea to make things easier would be to use the id that these objects have (from a datastore) and allow the list directive to iterate over object properties. For example, one would map data back from a db like this

view = new Ractive({
  data: {
     rows: {
          '434342' : { id: '434342', name: 'Ryan' },
          '434343' : { id: '434343', name: 'Rich' }
     }
  }
});

and the template

   <ul>
     {{#rows}}
          <li data-id={{key}}>{{value.name}}</li>
     {{/rows}}
   </ul>

and to do an update

view.set('data.rows["434342"]', {id: '434342', name: 'Rob'});

This is non-standard mustache but I think it makes sense in terms of allowing data-binding with large lists.

@Rich-Harris
Copy link
Member

I've wrestled with this one in the past. In fact I got half-way to implementing it but changed my mind because of two main reasons:

  • 'Object sections' already have a meaning in mustache - providing context for their contents. To enumerate over object properties we'd need to add some syntax that said 'treat this as an iterator, not as context'
  • Browsers sort object keys inconsistently, and provide no guarantees even of internal consistency. Even in cases where the data order doesn't matter, it could conceivably lead to all sorts of weirdness (add an item and the list reorders itself, that sort of thing)

The solution I eventually settled on (disregarding my own objection to non-standard syntax!) was declaring an 'index reference' with each iterator section using a colon, like so:

<ul>
  {{#rows:i}}
  <li data-row='{{i}}'>{{name}}</li>
  {{/rows}}
</ul>

This makes it straightforward to identify which list item a user has clicked on, for example. (The index reference doesn't have to be i - could be id, num, whatever.)

But I realise it doesn't much help if the data comes as a hash of key-value pairs. Typically my own approach in these situations is to maintain two views of the data - an array, and a lookup table with ids as key, though that isn't always ideal.

We could conceivably use the colon syntax as the 'treat this as an iterator, not as context' directive, and internally create an array representation of the data, though I'm not sure off the top of my head what other issues it would raise.

What do you reckon? Does the index reference mechanism solve the problem?

@ryanramage
Copy link
Contributor Author

yeah, I can see now how you probably have wrestled with this issue. Iterating over the object is really not the solution. For now I can use the index reference and keep an id to position map, which was the way I was going to originally approach it.

Throwing another potential way into the mix. Again this is a top of my head with not much thought on the impact...

view = new Ractive({
  data: {
     rows: [
         { id: '434342', name: 'Ryan' },
         { id: '434343', name: 'Rich' }
     ]
  }
});

template

   <ul>
     {{#rows}}
          {{#id | id-section}}
                <li data-id={{id}}>{{name}}</li>
          {{/id}}
     {{/rows}}
   </ul>

set the id-section

view.setId('434342', {id: '434342', name: 'Rob'});

It looks reasonable to me. The thing I dont like about this is that it short-cuts actually using the data model and can only be used by the template. So any other observers on the data model would not see the change. hmmm. Will have to give this more thought...

@Rich-Harris
Copy link
Member

Yeah, it's tricky. There's actually a deeper question here I think, which is the extent to which a tool like Ractive should be responsible for managing the model, as opposed to merely displaying it.

Generally I try to avoid using MV* jargon because it gets abused enough already, but when I need to, I refer to a Ractive instance's data property as a viewmodel, rather than a model (similar to Knockout).

Possibly a philosophical distinction, but I'm trying to avoid the trap of adding too much model management stuff (validation, derived values, synchronisation etc) because there are already better tools for that, and I want to build a library rather than (yet another) framework.

But the temptation to make it 'full stack' is always there! I'll close this issue for now, but if you have any further thoughts on it then don't hesitate.

@thiagovidal
Copy link

Hi, I'm trying to do almost the same as @ryanramage. Any change on this topic?
I really need to keep index of objects!!! If you could help me I will be very grateful.

@thiagovidal
Copy link

Thanks @Rich-Harris!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants