Skip to content
This repository has been archived by the owner on Mar 13, 2018. It is now read-only.

Should be able to <template repeat> on object values just like we do on array values. #116

Closed
krisnye opened this issue Jun 26, 2013 · 10 comments

Comments

@krisnye
Copy link

krisnye commented Jun 26, 2013

It would also be nice for both arrays and objects to be able to have an index value available for binding. For instance:

<template repeat="{{ myarray }}" index="i"> {{ i }} {{ somevalue }}</template>

Demonstration of object repeat template not working:

<!DOCTYPE html>
<html>
  <head>
    <script src="polymer.min.js" debug></script>
    <element name="v-bug">
        <template>
            Array Template:
            <template repeat="{{arraydata}}">
                {{}}
            </template><br>
            Object Template:
            <template repeat="{{objectdata}}">
                {{}}
            </template>
        </template>
        <script>
        Polymer.register(this, {
            objectdata: { alpha: 1, beta: 2, charlie: 3 },
            arraydata: [1,2,3]
        });
        </script>
    </element>
  </head>
  <body>
    <v-bug></v-bug><br>
  </body>
</html>
@rafaelw
Copy link
Contributor

rafaelw commented Jun 26, 2013

I think the filters implemented by the syntax can handle this. I don't know what the right syntax is but something like

<template repeat="{{ myObj | someFilterThatObservesObjectAndExposesConsistentArray }}">

The access to index is a separate issue. Opened another bug here: #117

@krisnye
Copy link
Author

krisnye commented Jun 26, 2013

How you implement this does relate to the index issue. If you use a filter that maps the object to an array, then you will lose the key/index.

I think of the index as the key for the value in the array or object.

If I iterate over { "kris": 1, "bob": 2 } then I would expect the index, value pairs to be [["kris",1],["bob",2]].
If you map this to an array though then we would get [[0,1],[1,2]].

The MDV templating syntax should ideally not require developers to structure our data in any particular way. If it does, then we have to go through an intermediate step of converting our data to a MDV friendly model before using it. This is difficult, and means we must also manually watch our original data for changes. Not good.

I would like to use my data in whatever format I keep it, and we don't always keep our items in arrays. We use objects as hashtables very frequently to store items.

@arv
Copy link
Contributor

arv commented Jun 26, 2013

I've said it before and I'll say it again. I think the right solution is to follow the for-of path of ES6. Here are some examples from ES6.

var array = ['Hi'];
for (let value of array) {
  print(value);  // 'Hi'
}

for (let key of array.keys()) {
  print(key);  // '0'
}

for (let [key, value] of array.enties()) {
  print(key);  // '0'
  print(value);  // 'Hi'
}

So applying this to MDV repeat:

<template repeat="{{value of array}}">
  {{value}}
</template>
<template repeat="{{key of array.keys()}}">
  {{key}}
</template>
<template repeat="{{[value, key] of array.entries()}}">
  {{key}} {{value}}
</template>

@rafaelw
Copy link
Contributor

rafaelw commented Jun 26, 2013

@arv I like that alot.

@rafaelw
Copy link
Contributor

rafaelw commented Jun 26, 2013

Strawman:

-Support "ES6-like simple destructuring syntax for named scopes". e.g.

<template repeat="{{ [index, user] of entries(user) }}">

Where this isn't really full destructuring (you can't do [index, [id, name]] of...), but it does work for a accessing the first two items of an element array.

The entries() is a filter which observer the underlying array (and keeps the key values correct if it mutates). (Note that we're still not settled on how filters work -- the right side of the above expression may change syntax).

This has the benefit of:

-not having to choose between picking a magical index/key name that may collide with user data...or picking some weirdo identifier.
-it allows multiple key/index values to be in scope, e.g.

<template repeat="{{ [userIndex, user] of entries(user) }}">
  <template repeat="{{ [projectIndex, project] of entries(user.projects) }}">
    <!-- userIndex and projectIndex are both accessible here -->
  </template>
</template>

I think this is implementable, though I can imagine wrinkles arising. Thoughts?

@rafaelw
Copy link
Contributor

rafaelw commented Jun 26, 2013

@krisnye, I guess I've proved your point that these issues are related =-).

@justinfagnani
Copy link
Contributor

FWIW, I've been implement comprehensions in the Dart custom syntax I've been working on (with the goal of compatibility with Polymer). So far I've been using Dart-like "in" syntax, with some additional sugar. For example:

<template repeat="{{ a, b in myMap }}">

or

<template repeat="{{ x*x as y for x in range(0, 10) where x % 2 == 0 }}">

So far so good. I prefer "in", like Python comprehensions and for..in loops, but JS and I presume Polymer will use "of" so that seems a clear way to go. I like brackets for introducing identifiers as it allows multiple identifiers to be added with "as" even for lists:

<template repeat="{{ [x*x as y, x] for x of range(0, 10) }}">

or

<template repeat="{{ [index, user.name as name, user.id as id] for entry of enumerate(users) }}">

(where enumerate() is like Python's)

@krisnye
Copy link
Author

krisnye commented Jun 26, 2013

I like the ES6 compatible syntax as well.

@arv
Copy link
Contributor

arv commented Jun 27, 2013

@justinfagnani I don't think we can really do iterables like what you showed with the comprehension example. To support iterables we would have to reiterate using dirty checking because iterables have no state and no notifications about changes.

Maybe you are just suggesting to use the same syntax and implement all of these as filters?

FWIW, the comprehension syntax in ES6 is:

[for (x of range(0, 10)) if (x % 2 == 0)  x * x]  // array
(for (x of range(0, 10)) if (x % 2 == 0)  x * x)  // iterator with next()

@rafaelw
Copy link
Contributor

rafaelw commented Nov 28, 2013

moved to: googlearchive/polymer-expressions#11

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

No branches or pull requests

4 participants