Closed christianalfoni closed 9 years ago
Let suppose we got /messages/42
as url:
controller.signals.urlChanged({url: '/messages/42'});
urlChanged
signal calls route
actionroute
actions sets url
state and using router service outputs to message
path providing id = 42
.messageActionChain
actions will set currentView
to message
and displayedMessageId
with 42
state value.Now how to proceed in reverse path? As I remember you declared that view shouldn't know anything about urls and routing. So I suppose that setting displayedMessageId
or currentView
state values from any action would change url accordingly. How would you suggest to achieve it?
Sounds like a really great solution. Looking forward to swapping out v1 for v2.
Maybe it would be worth to borrow a couple of functions from page.js or similar to do the url parsing. Then you can maintain the existing functionality with regards to the url data being passed to the next action.
Hi @Guria and thanks for the comment,
The "other way around" is calling signals.urlChanged
manually. So:
controller.signals.urlChanged({url: '/someUrl'});
addressbar.on('change', function (event) {
event.preventDefault();
controller.signals.urlChanged({url: event.target.value});
});
What I meant about "VIEW layer should not know about urls" is that your VIEW layer does not check the URL to figure out what to render. It still uses a URL as input to output actual application state changes. And those mapped state changes are what the VIEW layer uses... if that makes sense :-)
So one way is:
urlChanged
-signal, where url and other state is setThe other way is:
urlChanged
-signal with a url, where url and other state is setIt would be interesting to look at solutions where certain state is related to certain parts of your url. So changes to currentPage
would automatically be /pages/{currentPage}
etc. I think that would quickly become quite complex, but url-mapper
is just one way of handling urls and state. A different lib could use addressbar
to achieve what you are saying here, though I am not quite sure how you would express that. Hm... you would probably have to do something like this:
So instead of speifically setting the URL in the urlChanged
signal you would dynamically create it based on state inside your tree.
controller.on('change', function () {
var url = createUrlByState(controller.get());
addressbar.value = url;
});
It is a really interesting concept, but you would have to somewhere define what each "section" of the url means. So /messages/123
-> [['currentPage'], ['messageId']]
, would map the url and insert state directly into those paths. Though reversing is really hard I think... hm...
You know, it would be fantastic to automatically produce urls back/forth just based on state and with the addressbar
it is possible, there just has to be a different implementation than url-mapper
to do it. Have to think about it a lot more :-)
So the goal now was to map urls to application specific state, which is to be used by the VIEW layer. You still use URLs to map to correct state changes. But yeah, removing the url completely and just map state values to a url would be really cool!
@garth @bfitch has been working on the url parsing stuff, not sure if he dived into some existing implementations, but yeah, that is a good idea :-)
@garth @christianalfoni What's in the v2 branch right now are just a couple functions that can parse urls with dynamic segments /foo/:id/bar/:guid
into an JS object {ud: '123', guid: 'abc'}
. I think once we have a solution for parsing query params we should be set, I think? I assume there's a small, well tested library out there that just handles parsing query params into objects (including complex arrays and nested objects). If not, I could take a crack at writing one.
Re: mapping app state to url "sections".....what if you used query parameters!?!
http://myapp.io?currentPage=messages&messageId=123&.....
then each time you change the state with a signal, you serialize the current state into query params. Then the query parser can parse that query string back and set
as your new app state. Maybe a silly idea...but I've actually been thinking about trying this for a bit. I think it's a possible solution to "automatically produce urls back/forth just based on state".
Looks like this is a good option for query strings: https://github.com/hapijs/qs . Maintained by the hapi.js framework and with zero dependencies.
Okay, so me and @bfitch has been playing around with the project I think we cracked it!
Take a look at this reasoning:
So there are now two projects: addressbar and url-mapper (no repo yet). So conceptually this is what they do:
addressbar
Makes the addressbar in the browser work like an input. This means that you can listen to url changes and you can set the value of the addressbar without causing side effects. This has nothing to do with routing, it is just a prerequisite for a reactive approach.
url-mapper (Please suggest other names)
This library just takes a url and maps it to a function. Parsing out params, and soon queries.
So now we have the two building blocks we need to do something pretty awesome in Cerebral:
How it works with Cerebral
First we expose our url-mapper as a serivce.
controller.js
Now we create ONE signal that will handle all the routing.
main.js
So the beauty of this is:
I am making a video on this today, please let me know if you have any initial thoughts. I will make sure to make an example with transitions :-)
You can test this by cloning the V2 branch,
npm install
andnpm start