Lets say we have a component in Aurelia named UserRouter, which is a child router and handles routing to UserProfile, UserImages and UserFriends.
I want the UserRouter to load in the user from the API (on canActivate) and then pass this this user data to sub components.
Loading in the data is fine, how do I pass it down to sub components so they can all read it? e.g. placing an attribute on <router-view>
.
I've tried the bindingContext argument on the bind() method of sub components but this hasn't worked.
Thanks
Lets say we have a component in Aurelia named UserRouter, which is a child router and handles routing to UserProfile, UserImages and UserFriends.
I want the UserRouter to load in the user from the API (on canActivate) and then pass this this user data to sub components.
Loading in the data is fine, how do I pass it down to sub components so they can all read it? e.g. placing an attribute on <router-view>
.
I've tried the bindingContext argument on the bind() method of sub components but this hasn't worked.
Thanks
Share Improve this question edited May 26, 2015 at 20:48 Mike asked May 25, 2015 at 21:43 MikeMike 7,7045 gold badges22 silver badges27 bronze badges 2- Have you thought about using a shared state? – Matt McCabe Commented Jun 14, 2015 at 8:52
- 2 check out Patrick Walters' post on sharing and passing state – Matt McCabe Commented Jun 14, 2015 at 8:59
5 Answers
Reset to default 6The way I did this, was by adding additional information to the child router definition eg:
configureRouter(config, router){
config.map([
{ route: [''], name: 'empty', moduleId: './empty', nav: false, msg:"choose application from the left" },
{ route: 'ApplicationDetail/:id', name: 'applicationDetail', moduleId: './applicationDetail', nav: false, getPickLists : () => { return this.getPickLists()}, notifyHandler : ()=>{return this.updateHandler()} }
]);
in the first route from this example, I pass in a text message by adding my own porperty 'msg' to the route object. in the second route I pass in some event handlers, but could have been some custom objects or antything else.
In the childmodel I receive these additional elements in the activate() method:
export class empty{
message;
activate(params, routeconfig){
this.message=routeconfig.msg || "";
}
}
I guess in your case, you would add the user object to the child router definition.
You could bind the router/user object to the <router-view>
<router-view router.bind="router"></router-view>
I have the same issue, so I'd love to see what you come up with!!
You could use the event aggregator to publish out an event with the data and the sub components could subscribe and listen for that event. This would avoid coupling between them. However, there may be a downside I'm not thinking of.
I worked out a solution for this, you simply tell the dependency injector to inject an instance of your parent router component using Parent.of(YourComponent).
import {inject, Parent} from 'aurelia-framework';
import {UsersRouter} from './router';
@inject(Parent.of(UsersRouter))
export class UserImages {
constructor(usersRouter) {
this.usersRouter = usersRouter;
}
activate() {
this.user = this.usersRouter.user;
}
}
You can also actually miss out the Parent.of part because the Aurelia DI system works its way up.
import {inject} from 'aurelia-framework';
import {UsersRouter} from './router';
@inject(UsersRouter)
export class UserImages {
constructor(usersRouter) {
this.usersRouter = usersRouter;
}
activate() {
this.user = this.usersRouter.user;
}
}
You can implement a generic method to pass objects:
configureRouter(config, router){
this.router = router;
...
this.router.navigateWithParams = (routeName, params) => {
let routerParams = this.router.routes.find(x => x.name === routeName);
routerParams.data = params;
this.router.navigate(routeName);
}
}
then you can use it programmatically like:
goToSomePage(){
let obj = { someValue: "some data", anotherValue: 150.44}
this.router.navigateWithParams("someRoute", obj );
}
finally, you can get the param on the destination page:
activate(urlParams, routerParams)
{
this.paramsFromRouter = routerParams.data;
}