Open nsatragno opened 9 years ago
This is a tricky one that I've tried to come up with a solution to before.
Here's a partial workaround.
<app-route path="/post/latest" import="components/x-post.html" element-attributes="post-id: 10"></app-route>
This could be written like this with the current API.
<app-route path="/post/latest" import="components/x-post.html">
<template><x-post post-id="10"></x-post></template>
</app-route>
The problem is other path variables would never be passed through (post-num
in this example).
<app-route path="/post/:post-num" import="components/x-post.html">
<template><x-post post-id="10" post-num="???"></x-post></template>
</app-route>
The tricky part becomes the syntax. How would you pass multiple attributes? How would you determine the type of the attribute? In polymer you can even bind JS objects as attributes.
<app-route path="/post/latest" import="components/x-post.html" element-attributes="post-id: 10, other-attr=hello world, yet-another={'property': '123'}"></app-route>
or separate them out like this.
<app-route path="/post/latest" import="components/x-post.html" post-id="10" other-attr="hello world" yet-another="{'property': '123'}"></app-route>
But then how do you know which attributes to pass, or just pass all attributes...
In short, it's tricky and I haven't come up with a simple solution.
Thanks for looking into this. What if you used plain old JSON and relied on the browser's native parser to infer types?
<app-route [...] element-attributes="{post-id: 5, some-other-attribute: {some-arg: 'string', some-array: ['1', '2']}}"></app-route>
Arguments that are on the element-attributes
tag should probably be overwritten by query or route parameters if these do come with the request.
This would be somewhat similar to what Polymer does to let you to pass objects and arrays through attributes. Granted, the syntax is certainly not the prettiest, but it would still be a very useful feature.
What do you think?
Polymer actually has an entire library dedicated to data binding called Node.bind() https://www.polymer-project.org/docs/polymer/node_bind.html.
In reality the router doesn't do proper data binding. All it does is parse the URL and calls element.setAttribute('attr', value)
.
Node.bind()
goes a lot further.
<x-input value="{{name}}"></x-input>
you are actually binding to the value property, not the value attribute. It only binds to the attribute if you publish the property as "reflected" in Polymer.Basically there's a lot of stuff going on there that the router is ignoring because it's only dealing with the URL. Once you dive into real data binding it gets complicated quick!
Wow, the actual issue is much more complex than I had expected. The router doesn't use Node.bind()
because it also has to work without Polymer, right? In this case, maybe it's worth adding it as a dependency?
I haven't delved deeply into WebComponents, so perhaps I'm missing important details.
In any case, I really appreciate the fact you are being so open to discussing your project. Cheers!
Yeah, right now there are no external dependencies. I've considered the possibility of making a Polymer specific router but I really don't want to maintain two forks. With Node.bind()
there's still the issue of determining which attributes to bind. Maybe something like this...
<app-route path="/customer/:customerId" element="customer-pages" bind-attributes="one two three" one="{{myValue}}" two="test string" three="{{objectReference}}"></app-route>
I'm adding this feature as a follow up to another PR https://github.com/erikringsmuth/app-router/issues/45. I'm hoping to get it released in v2.1.0 this weekend.
It'd be a partial workaround for this issue. You could achieve the same thing but with JS instead of HTML. It's not quite as clean but it's a start.
2.1.0 is up. Take a look at the before-data-binding
event. This might get you close enough.
https://erikringsmuth.github.io/app-router/#/events#before-data-binding
That's great! After merging #47, it's the perfect solution for us as we build the router with JS.
@nicolassatragno @erikringsmuth How would you use before-data-binding to have it set the attributes to app-route? I'm trying to do data-binding with native web components. I can get the partial to appear but the path variables aren't being tied to anything. Would using before-data-binding help me set those attributes on app-route or something where I can access the attributes?
It would be really cool if we could set element attributes on the
<app-route>
tag, like this:components/x-post.html
:Besides being a good feature on its own, this would make working with the new
core-animated-pages
integration much nicer if animations in which relative section position matters are used, such asslide-from-right
.