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

Implement sort and filter array filters #13

Open
rafaelw opened this issue Nov 28, 2013 · 9 comments
Open

Implement sort and filter array filters #13

rafaelw opened this issue Nov 28, 2013 · 9 comments
Assignees

Comments

@rafaelw
Copy link
Contributor

rafaelw commented Nov 28, 2013

Moved from: googlearchive/TemplateBinding#103

@ajklein
Copy link

ajklein commented Jul 29, 2014

Talked about this today with @esprehn. For filtering, we came up with a strawman syntax:

<template repeat="{{ foo in foos where foo.barCount > 0 }}">
  ...
</template>

From my (naive) understanding of polymer-expressions, this looks pretty "simple": generated binding observs both foos and, for each element in foos, barCount. The right side of the where, to start, should just be a normal polymer-expression.

@addyosmani
Copy link
Contributor

This would save on us having to keep implementing custom filter(x) expressions, so hooray for progress! You mentioned foo.barCount in your example. How well would the machinery you had in mind cope with more complex data structures?

@ajklein
Copy link

ajklein commented Jul 29, 2014

@addyosmani I think that's an excellent question, but it may be separate from the issue of providing filtering/sorting in template repeat. As I noted above, the thing on the right of "where" is just an expression.

For example, suppose each foo had an array of bar, and each bar had a bazCount. We'd like to be able to express "foo in foos where foo.bars contains a bar with bazCount > 0". @esprehn suggested another strawman:

<template repeat="{{ foo in foos where foo.bars[$].bazCount > 0 }}">

The [$] syntax indicates to the expression system that the entire array needs to be observed, along with the bazCount property of each element. This would be useful outside of a repeat:

<template if="{{ foo.bars[$].bazCount > 0 }}">

I don't see a need to tie these two capabilities, though I agree that they would be useful together. In fact, #31 hints at some of the same issues (needing to express a broader set of dependencies than a path from an object).

@sjmiles
Copy link
Contributor

sjmiles commented Jul 30, 2014

Originally the notion was to try to emphasize JavaScript over declarative syntax for a couple of reasons.

One issue is that JS filter functions go directly on the prototype and then are shared. This kind of construction has to be parsed and interpreted per-instance. Is this a real concern?

Another is that the view template can become spammed with data logic that is more properly expressed in the model or the presenter. But I suppose this is mostly a slippery-slope argument, and is much less convincing.

@esprehn
Copy link

esprehn commented Jul 30, 2014

The problem with doing this imperatively is that you then need to build the "kick" system to keep telling the template binding framework which <template>'s to re-evaluate, and the template system also doesn't understand the relationship between the filtering and the object graph so it can't do anything smart.

I'd expect to be able to use this in a computed property so the template isn't crazy.

    computed: {
      filteredFoos: "foo in foos where foo.bars[$].bazCount > 0"
    }

and later

    <template repeat="{{ foo in filteredFoos }}">

@ajklein
Copy link

ajklein commented Jul 30, 2014

Re-parsing again seems like a separate issue. I don't see any reason why we should be re-parsing bindings expressions per-instance; if we are, it sounds like a nice optimization to be made.

I definitely see the "too much logic in the template" argument, and it's why I wanted to think of the extended expression syntax for object/array observation as an extra addition. My first comment suggested that for starters, we could simply support any existing expression on the RHS of where in a repeat, since we know it's a common case and the logic you'd have to write in JS to get the right behavior is boilerplate (thus ripe for being generated by the framework).

@sjmiles
Copy link
Contributor

sjmiles commented Jul 30, 2014

Thanks for the thoughts guys.

If we can put the expressions in the computed object as Elliott suggested, it seems like it solves my problem and supplies the binding system with the enhanced information (which was intended when we decided to use expressions in that object). That's +1 afaict.

@jmesserly
Copy link
Contributor

seems like a good idea.

I see the "where" syntax proposal, would it also include some kind of "sort by" as syntax?
disclaimer: the reason I ask is the issue title is "sort and array filters". I'm not necessarily advocating this :)

But here is an example:

<template repeat="{{ foo in foos order by foo.score }}">
  ...
</template>

@jmesserly
Copy link
Contributor

Another idea would be to reverse precedence between repeat and if, such that:

<template repeat="{{ foo in foos where foo.barCount > 0 }}">

could be written as:

<template repeat="{{ foo in foos }}" if="{{ foo.barCount > 0 }}">

that's a backwards from the current precedence, though. Yet another thought is:

<template repeat="{{ foo in foos }}" where="{{ foo.barCount > 0 }}">

One good point in Polymer/old-docs-site#583 -- due to the need for template attribute on IE such as <option template repeat="...">, it's important to not require nesting <template> inside <template>, since that can't be expressed in the template attribute form.

edit: formatting

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

6 participants