-
Notifications
You must be signed in to change notification settings - Fork 48
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
Iteration API #12
Comments
I've got a branch with this stuff actually, forgot about it, there's a few things I wanted to try with composition but the basic iteration stuff I was just doing to do |
sounds clean, do push |
I'd really like for this to support iterating through an array of primitives. This was one of my main issues with rivets. Something like: fruits = ['apple', 'orange', 'pear']; <ul each="fruit in fruits">
<li><span data-text="fruit"></span></li>
<ul> outputs: <ul>
<li><span>apple</span></li>
<li><span>orange</span></li>
<li><span>pear</span></li>
<ul> |
Perhaps formatters could be used via <ul data-each="fruit in fruits | toObject">
<li><span data-text="fruit"></span></li>
<ul> var fruits = ['apple', 'orange', 'pear'];
var fruitView = {
toObject: function(val) {
return { fruit: val }
}
}
// edit: the data-each="fruit in fruits" would require a key 'fruits'.
reactive(el, {fruits: fruits}, fruitView)
// edit: perhaps 'this' could be used so you don't have to supply any object key
// e.g. <ul data-each="fruit in this | toObject">
reactive(el, fruits, fruitView) |
Also, being able to iterate over a hash would be useful. e.g. var fruits = {
apple: {
price: 2
},
banana: {
price: 7
}
}
reactive(el, fruits, {
toObject: function(val) {
return {
fruit: val
}
}
) <ul data-each="name, fruit in fruits">
<li><span data-text="name"></span><span data-text="fruit.price"></span></li>
<ul> Output: <ul data-each="name, fruit in fruits">
<li><span data-text="name">apple</span><span data-text="fruit.price">2</span></li>
<li><span data-text="name">banana</span><span data-text="fruit.price">7</span></li>
<ul> |
@visionmedia hey can you push that branch so i can have a play with it, even if it's not complete? |
@timoxley @matthewmueller I notice that you put the Please share your reasoning! ..and yes I'd also like @visionmedia to share his implementation of this feature. |
sorry haven't had time to get an example with it working yet to push the branch, it's in flux ATM |
@karlbohlmark looping over a block is much more flexible than looping over a single element. Also, in rivets, they could have just changed: <ul>
<li data-each-tag="item.tags" data-text="tag:name"></li>
</ul> to: <ul data-each-tag="item.tags">
<li data-text="name"></li>
</ul> IMO this makes more sense. |
@matthewmueller I fail to see how it makes more sense to put the looping construct on any other element than the target for repetition. Say you want a template for a table <table>
<caption>Please don't repeat me, I'm just a caption!</caption>
<tr each="item in items"><td><button data-text="item.action"></button></td></tr>
</table> How would you do this with the |
do you mean To be clear though: I'm not arguing against having a single repeating element. I could definitely see a use case for it, I just think iterating over a block is more useful. |
@matthewmueller Above example has invalid html table structure, I think that's what's obscuring the intent… I believe it's trying to demonstrate a case where you have a repeated item which doesn't necessarily have a shared parent element, e.g. <h1 data-text="essay.title"></h1>
<p each="paragraph in essay.paragraphs" data-text="paragraph"></p> Otherwise you'd be forced have to have all the |
Sorry, I accidently left out the td. @timoxley you got it. What's your take? |
Basically I see these scenarios:
Approaches: A) means you always have to wrap with a parent element, but then you can handle 2) and 3) and some cases of 1) If this was a compiled language I would suggest we introduced an |
To be expressive, reactive should probably support both. I can't see any way you can safely differentiate which looping system to use using the same syntax though… perhaps just need a different keyword? <p each="paragraph of essay.paragraphs" data-text="paragraph"></p>
<!-- vs. -->
<p each="paragraph from essay.paragraphs" data-text="paragraph"></p>
<dl data-each="def in definitions" data-id="definitions.name">
<dt data-text="def.term"></dt>
<dd data-text="def.definition"></dd>
</dl> Or perhaps something completely different. I think we should probably just wait until there's any working implementation and then we can continue the speculating. |
too many options is a -1 from me but I see what @karlbohlmark is saying, to me block was what I was drawn to as well, seems more natural coming from a for loop I suppose but I definitely agree that on the element itself is better. we can get a reasonable look without preprocessing though, |
ahh my bad, I misunderstood what you were saying @karlbohlmark. You're just saying copy the parent (e.g. |
initial stuff: https://github.com/component/reactive/compare/add;iteration few notes:
we could handle changes by simply clobbering and reiterating but that kinda gets back to just being a regular old shitty static html template engine, not ideal IMO |
also instead of opting-in to access the parent as shown here: https://github.com/component/reactive/compare/add;iteration#L0R28 we could do the opposite where it's always scoped to the child object like here: https://github.com/component/reactive/compare/add;iteration#L0R20 and then use |
could you just use "this" to reference the child. |
+1 for scoping to the child object I think clobbering and reiterating is the only way to go, I'm not sure it'd be worth the trouble to make it more granular than that. |
Do we save a detached clone of the template element to use in subsequent rendering? |
@karlbohlmark yup, the first one is discarded ATM after use but we'll need to store it and make the thing reactive |
RE accessing parent scope: handlebars uses <span data-text="../name">Name</span> While it looks a bit gawky, at least it has a familiar meaning. Also +1 auto scoping to the child. This also matches handlebars behaviour: {{#each comments}}
<h2><a href="/posts/{{../permalink}}#{{id}}">{{title}}</a></h2>
<div>{{body}}</div>
{{/each}} |
I think I'm -1 on auto scoping to the child, because that's more like a |
Introducing new names into scope is expected to be explicit. Principle of least surprise. |
@karlbohlmark In the branch both formats work: |
@matthewmueller clobbering isn't very elegant and especially in the case of lists, could be very expensive/flickery. Would be cool if reactive could re-sort items automatically, ala http://substack.net/projects/sorta-vote/
|
I think a parent scope isn't always necessary ? Wouldn't you typically add What I think you do need is access to the original root of the view (like |
@weepy parent scope is very useful. IIRC this was a pain point using mustache. You'd have to go in and write loops in your view code just to gain access to data you were just using 2 lines prior. |
Another issue is passing an array directly to reactive: var items = [item1, item2, etc]
reactive(el, items) how would I refer to the array to iterate over it? perhaps <ul each="this">
<li data-text="title"></li>
</ul> |
to avoid the parent think |
any updates on this? i'd be really interested in such a feature. |
Done in The syntax is as follows: <ul>
<li each="todos">{name}</li>
</ul> The item with the |
wow, awesome. |
Adding child items to the parent element manually sucks. Also means the list itself isn't reactive, only it's elements (and only while they exist).
Also made more painful by #5 because you have to do a little dance to remove the parent and render the child element (e.g.
<li>
or<option>
) as in example below:I guess copying rivet's style again wouldn't be too bad:
What do you think? Is there a better API?
The text was updated successfully, but these errors were encountered: