Closed wycats closed 11 years ago
About the recognizer btw: it uses a state machine, where every state consists of a set of "validChars" or "invalidChars" and a "repeats" flag (which is used in dynamic segments / star routes). A static segment ("/posts") is represented by a state for each of the characters in its path with a validChar equal to its letter (p, o, s, t, s; ), where the final character is an accepting state with a handler. A dynamic- / star segment has one invalidChar ("/") and repeats (and is also accepting).
While it's technically possible to implement query strings into this state machine, it is currently generated as a tree; so adding optional states behind every handler would make the tree exponentially larger in the number of handlers. Apart from that it would also be difficult to implement. Actually I'd say this system is a sort of regex-engine; but then why not use the one that Javascript ships with ;).
The way I "solved" this problem is by replacing the single-character states with states that consist of a regular expression, so there's a state for every "/" separated portion of a path. This allows adding an optional query string to some of them. That being said it is still quite complicated; and I personally think it would not be a horrible idea to change it altogether.
Can we have the cake & eat it too? Matrix params for route local context & query style for global context?
/posts/5/comments?author=alexspeller # author param affects all routes /posts;author=alexspeller/5/comments # affects only posts route /posts/5/comments;author=igor # affects only comments route /posts;author=alexspeller/5/comments;author=igor # split /posts;author=alexspeller/5/comments;author=igor?sort=oldestFirst # split w. global
@igorbernstein Too much cake.
I can't really think of a compelling use case for this that couldn't be handled by a leafier route looking up information on the parent route that was passed a per-route query string. It shouldn't be ambiguous which route will be using the author=
information. Forcing per-route query strings would remove that ambiguity.
edit: :cake: :cake: :cake:
Hmm also not sure it's desirable. I can probably think of a use case for it, but then you'd have to explain to everyone why there's two types of query strings, which takes preference and when and how they're updated.. We'd spend all day in the kitchen only to see our guests stare in doubt at our cake, which is an octahedron with whipped cream on all sides.
I've got a decent workaround by create an outer controller that has no view or templates:
/todos/p/key:value,key:value
Application => Todos => TodosParams
It works with the controller context stack and reaching up in the stack to pull arguments from a params controller that sits below the desired controller's route.
When you need parameters, you need the params controller, and set a paramsBinding: "controllers.params"
A rough example how to do it manually is here: https://gist.github.com/Nthalk/5407240
A more involved helper function exists here: https://gist.github.com/Nthalk/5409344
Edit: This method doesn't work well, see my below comment for my revised strategy
@Nthalk thanks for sharing, simple and useful!
Agreed! @Nthalk could you post a full jsfiddle with a sample app using this? I'm trying to use a model route and found that having "params" be a string that represents multiple model properties a bit awkward so I'm sure I'm just doing it wrong :)
Okay, after diving into that for a while, I realized my above solution didn't work that well, and there was a different, more usable way of dealing with it:
http://jsfiddle.net/fdkPY/7/ NOTE: jsfiddle isn't showing the underlying routes in the address bar. They're being hidden in some iframe, but they do reflect dynamic parameters.
The one major caveat of this method is that it crowds the url space. Whereas you once had:
todos # todos.index
todos/:todo_id # todos.show
...You cannot use that uri space because it is taken by :params, so you must instead use something like...
todos/list/:params # todos.index
todos/:todo_id # todos.show
...so you don't collide with the resource routes. It's a small price to pay, but you can see from the jsfiddle that this method does indeed work and allows extensions into the show routes:
todos/:todo_id/:params # todos.show withParams
In my projects lib, I'm planning on adding a WithParams mixin that does the generic parameters lifting.
Additionally, there can be an observer that listens to changes on the params and updates the current URI via transitionToRoute, but that's best left to the developer to decide if calling transitionToRoute on an observer is sane.
This is super required for me to keep state within the url. Example: /session?tool=draw&theme=something&redirect_uri=something
Anyone taking a crack at this yet for a pull request?
@jayphelps have you tried my library?
@alexspeller I have indeed, but I require history and hash support both (I'm currently using my PR #2685 for AutoLocation). I'd be down adding that support to your library, but if this is indeed something the core team wants in the mainline I'm hoping we can get a PR rolling.
Ah ok. Well the problem is that my implementation is the most complete, however it's unlikely to be the officially adopted one. I haven't worked on matrix params at all, and am unlikely to in the very near future, although I'd be willing to at some point when I have more time.
Guys! I've been working on another query parameter workaround lately, and this one I'm pretty excited about. It can be found here: https://github.com/ElteHupkes/ember-query-params . Quick summary: global query string (not my preference, but less impossible to implement), works with linkTo / URL generation, Location independent, minor route configuration. For me personally this is the best solution thusfar - let me know what you think!
@ElteHupkes great contribution. Do you have an example app which demonstrates it's usage and benefits?
@cavneb I've cooked something up real quick: http://liveweave.com/QLJ0f1 . Unfortunately these JSFiddle type-things don't show the URL-bar, which really is kind of the point when showing query parameters ^^. You can copy-paste that LiveWeave's code into a HTML-document and it should work though.
Any questions, please let me know :)!
@ElteHupkes it worked great. Here's an example app: https://github.com/cavneb/ember-query-params_example
@cavneb Nice! I added a link in the README.
@ElteHupkes I've been a bit busy to update my libary for RC6 at the moment, but it seems our libraries are very similar, in fact when I do update my library I will probably be looking at yours and basing it mainly from your work as it does most of what I need. However I think there are one or two things my library does that yours doesn't (binding params to controller properties is the first one I can think of), and one thing I'm not too keen on with your library (I don't like the QueryParameters
and don't think it's necessary).
In any case, I'd like to ask if you'd be willing to work together on this problem and find a way to combine our efforts?
@alexspeller Definitely! I'll probably be too busy the upcoming weeks for any serious meddling with the query params (ok part of that will be a vacation, so maybe "unavailable" is a better term ;]), but I think it's a very good idea to put our heads together and start thinking about how we can combine our efforts and make things better for everyone.
Great! I will start working on some stuff, and I'll file some pull requests to your repo and put a note on my library to look there for RC6 support. Enjoy your holiday, and let's talk when you get back.
@ElteHupkes @alexspeller God bless both of you for working together to solve this. I wanted to try ember-query but it's not RC6 ready yet.. I already have an app that's near production using ember-query-params, which I really like.. I will integrate your combined efforts as they become available. Thanks again!
Thanks for taking this on @alexspeller and @ElteHupkes! I just grabbed ElteHupkes/ember-query-params and added it to a project I'm working on to give it a spin and wanted to chime in to agree with one of @alexspeller 's recent comments:
I find the QueryParameters
object a little unwieldy, especially regarding the linkTo
helper. I'd like to be able to specify my query params right in the template much like I do in my rails apps. I'm not experienced enough with Ember to know how/if this would be possible, but it would feel most natural to me.
Hi all,
This GH thread is becoming a Tolstoy novel, and I'd like to get some outside thoughts in since I doubt there's all that many people following this thread beyond some of the main contributors. So, if you will, please check out the following Discourse thread and summarize the various approaches you've taken, lessons learned, implementation status, etc., and see if we can't nail the best way to go going forward:
http://discuss.emberjs.com/t/query-string-support-in-ember-router/1962
I just pushed support for ember master here
hi alex
ember-query doesn't work in IE 9 , I added new issue with error message
Hi all, there is now a PR for this, please see #3182
Closing in favor of discussion on the PR.
@machty Indeed there's no reason we couldn't have that. Only determining which handlers need to be updated is not straightforward. Also it can't be done as a hack, you really need to modify some of the functions closed over by the router module (or copy a whole bunch of code). I suppose this is what has kept most people from implementing it, because I guess we're all working on getting our webapps to just work ;).
I agree the per-route querystrings make more sense conceptually, so I hope you guys have time to take a look at my implementation. Still needs some polishing, but the essential parts are there at least.