Whenever something is really, really hard to do in a library, I am almost certainly doing something really stupid. I love when that happens.
I love it because there is almost certainly something fundamental that I am missing. Something that the library wants me to do in a certain way. And if I can figure out that way, then learning starts. More importantly, the library starts teaching me why things are done that way. It's the why that I really love. The day that I learn why a framework has me do something a particular way is always a good day. Today is not one of those days. Today, I struggle through a really dumb solution—to Angular.dart routing.
I have routing working with the master branch of Angular.dart (which is the same as version 0.0.5). The default route in my calendar application points to a controller-backed list view of all appointments. A separate route points to a controller-backed individual appointment detail view. The routing works fine. The controllers attached to the two views work fine.
The problem is that I cannot figure out how to get the
dayId
parameter in the route sent to the appointment detail controller. From last night, routing in in Angular.dart is currently implemented by the route_hierarchical package. In my calendar application, this looks like:class CalendarRouter implements RouteInitializer { void init(Router router, ViewFactory view) { router.root ..addRoute( defaultRoute: true, name: 'day-list', enter: view('partials/day_list.html') ) ..addRoute( name: 'day-view', path: '/days/:dayId', enter: view('partials/day_view.html') ); } }By virtue of the section route, I ought to be able to access
/days/42
URLs and the detail view controller should know to lookup record ID=42 from the backend via the dayId
parameter.Now, I know that there must be a very easy way to do this in Angular.dart, but after some time of searching and injecting and searching and injecting some more, I have come up empty. I know that, ultimately, I need a
Route
object from the route_hierarchical
package so that I can get access to the parameters
property. But I do not see how to get that object in the controller.From the
route_hierarchical
documentation, I know that the enter
named parameter to the addRoute()
is a function that receives a RouteEvent
object. The RouteEvent
object has a route
property. Perhaps that can help...The
view()
that is currently being assigned to the enter
named parameter is returning a function that takes RouteEvent
object as an argument. I still need to call that to get my Angular.dart routing working properly, but I also need to get that route
. This winds up fitting the bill:class CalendarRouter implements RouteInitializer { void init(Router router, ViewFactory view) { router.root // ... ..addRoute( name: 'day-view', path: '/days/:dayId', enter: (RouteEvent e) { print(e.route.parameters); return view('partials/day_view.html')(e); } ); } }Now when I access the day view route, I get the parameters dumped to the console:
{dayId: a7380ec0-17e0-11e3-a775-774b90ad8e75}That is only part of the battle. I have the
dayId
paramter in the route, but I need to get it to the controller somehow.And the best that I can think to do in this case is to inject scope into my router and then dump the parameters into scope:
class CalendarRouter implements RouteInitializer { Scope _scope; CalendarRouter(this._scope); void init(Router router, ViewFactory view) { router.root // ... ..addRoute( name: 'day-view', path: '/days/:dayId', enter: (RouteEvent e) { e.route.parameters.forEach((k,v) { _scope[k] = v; }); return view('partials/day_view.html')(e); } ); } }After injecting scope into the day view controller, I finally have access to that parameter:
@NgDirective( selector: '[day-view-controller]', publishAs: 'appt' ) class DayViewController { // ... DayViewController(Scope scope) { print('dayId: ${scope["dayId"]}'); } }And, when I load the page, I see my UUID
dayId
value logged to the console:dayId: a7380ec0-17e0-11e3-a775-774b90ad8e75So I have routing parameters working. But communicating through scope feels wrong. In plain-old AngularJS, it is possible to inject route parameters into objects. Angular.dart must have something similar—or some alternate approach that I am missing. Or perhaps it is still a feature in need of development?
Regardless, I have a really dumb routing parameters solution. And the promise of something better in the near future.
Day #915
Looks like not so stupid but not so good. Did you see https://github.com/angular/angular.dart.tutorial/tree/master/Chapter_05?
ReplyDeleteIt seems you need:
1. bind route to view: https://github.com/angular/angular.dart.tutorial/blob/master/Chapter_05/view/view.html#L1
2. inject RouteProvider: https://github.com/angular/angular.dart.tutorial/blob/master/Chapter_05/view/view_recipe_component.dart#L21
Then you can use routeProvider.route.parameters.
Don't like the need to bind route to a view in html. Such binding was already defined in *RouteInitializer. It looks like a bad responsibility for a template.
Thank you so much! I had not seen that and will give it a try today.
DeleteI think I agree with the dislike of binding routes in the view. Based on the discussion in the [RouteProvider](http://ci.angularjs.org/view/Dart/job/angular.dart-master/javadoc/angular.routing/RouteProvider.html), I thought something like this was needed. I was ultimately unable to figure out how to connect everything (the tutorial explains it nicely though), but even as I was getting close, it just felt like too much work.
Anyhow, I'll give it a try tonight and see how I like it. Much thanks for the pointers!