davidjamesstone / superviews.js

Template engine targeting incremental-dom
http://davidjamesstone.github.io/superviews.js/playground/
246 stars 15 forks source link

Feature Request: Each tag #31

Open dak opened 8 years ago

dak commented 8 years ago

Proposal:

Add an <each> tag that functions similar to the dual <if>, which can be used as an attribute or as its own node. each would take a single attribute, condition.

Syntax:

<each condition="item in list">
    <span>{item}</span>
</each>

Reason:

<div each="item in list" if="true">{$value}</div> has two different potential meanings:

<each condition="item in list">
    <if condition="true">{$value}</if>
</each>

and

<if condition="true">
    <each condition="item in list">{$value}</each>
</if>

however, only the latter example is possible with the current syntax.

alexsad commented 8 years ago

Maybe <each witth="item in list"> Or <with each="item in list">

davidjamesstone commented 8 years ago

I'm looking at doing this - I need it for doing something like this:

<table>
  <tbody>
  <each condition="item, item.id in list">
    <tr>
      <td>...</td>
    </tr>
    <tr if="item.isExpanded"> // include a second edit row
      <td>...</td>
    </tr>
  </each>
  </tbody>
</table>

The realisation I have encountered is around incremental-dom keys. Usually superviews autogenerates these on the element being iterated however the each above doesn't have an element. It would therefore put the onus back on the user to include one using the key attribute otherwise incremental-dom is unable to track the item correctly.

The above code would need to become something like this below:

<table>
  <tbody>
  <each condition="item, item.id in list">
    <tr key="{item.id}_item">
      <td>...</td>
    </tr>
    <tr if="item.isExpanded" key="{item.id}_edit"> // include a second edit row
      <td>...</td>
    </tr>
  </each>
  </tbody>
</table>

Or, making use of the transient $key autogenerated uuid variable available within the for loop:

<table>
  <tbody>
  <each condition="item, item.id in list">
    <tr key="{$key}_item">
      <td>...</td>
    </tr>
    <tr if="item.isExpanded" key="{$key}_edit"> // include a second edit row
      <td>...</td>
    </tr>
  </each>
  </tbody>
</table>

I don't really like the fact we lose autogenerated keys - it's easy to forget to put one on and the consequence is your dom tree will likely get out of sync.

I just can see an alternative ATM.

ferrugemjs commented 8 years ago

<with each="item in list"> looks nice.

davidjamesstone commented 8 years ago

I like it but I'm not sure this solves my issue though. Regardless whether we name it <each>, <for> or <with>, the onus will still be back on the user to identify the key.

ferrugemjs commented 8 years ago

Also other intuitive option <for each="item in list">

dak commented 8 years ago

@davidjamesstone: I only looked at the superviews transformation code briefly, so this is a little bit shooting from the hip, but can you do something similar to reference counting? — make the handler onopentag and onclosetag functions closures that reference a variable to track nested tag depth and if you're inside an each. If you're inside an each, increment on open, decrement on close, and if you're at the root inside an each, add a key.

I'm not sure how self-closing tags are handled, but you may need to keep a list of those and just not increment on them.

oravecz commented 7 years ago

I also have a need for a standalone each. I have two different <li> structures I want to use depending on an attribute in each item.

The bulk of the authoring was done last summer with a brief flurry in November. Is this an active project/library for you? (Just asking sincerely.)

davidjamesstone commented 7 years ago

Yeah I really need to look at implementing this. It seems it would be quite a useful feature.

It still an active project yes. I use it for a lot of my own projects, I just haven't had to change it much over the last few months.

I'm keeping an eye on the idom project and plan to keep it aligned with their api as it matures.

blikblum commented 7 years ago

I implemented each tag support at my fork:

https://github.com/blikblum/idomview/commit/30ec219db4e3201505d242b19c578fded7f57ead

https://github.com/blikblum/idomview/commit/907a091320e349741f6915a5491a553c41000131

Since this fork contains other changes i needed (see #41 #40) the merging is not straight forward but should not be hard to backport

davidjamesstone commented 7 years ago

Fantastic blikblum.

I'll take a look over it later. What other features does your branch contain? I'm wondering if I should bring it all over, including the unit tests et al.

Many thanks

blikblum commented 7 years ago

I implemented the following:

Also planning: