Aurelia: How to Navigate Between Child Routes

I try to move from one child route to another, but I constantly get Route not found . My main question is: how to navigate between child views?

Below is the code, and I will also have additional questions.

App-View Mode App Class:

 export class App { configureRouter(config, router) { config.title = 'My Site'; config.map([ { route: ['','job-view'], name: 'jobView', moduleId: './job-view', nav: true, title:'Jobs'}, { route: ['services'], name: 'services', moduleId: './services', nav: true, title:'Services'} ]); this.router = router; this.router.refreshNavigation(); } } 

Q.2 : why do we need to save the router here if it is always accessible from aurelia-router ?

Application Page:

 <template> <require from='./nav-bar'></require> <nav-bar router.bind="router"></nav-bar> <div class="container"> <router-view></router-view> </div> </template> 

So, now that we have our root pageview and nav, define job-view MV.

JobView Class:

 export class JobView { configureRouter(config, router) { config.map([ { route: ['','jobs'], name: 'jobs', moduleId: './jobs', nav: false, title:'Jobs', settings:{icon:'glyphicon glyphicon-align-justify'} }, { route: ['job/:id'], name: 'job', moduleId: './job', nav: false, title:'Job Details'} ]); this.router = router; //WHY SAVE THIS? this.router.refreshNavigation(); } } 

JobView Page:

 <template> <router-view></router-view> </template> 

Now here are the children's performances. My guess is that the occurrence of the route should be relative to job-view . This is what I want, ideally.

Vacancy class (for brevity, a bunch of code has been removed):

 import {Router} from 'aurelia-router'; @inject(Router) export class Jobs { constructor(router) { this.router = router; } toJob(id) { // this.router.navigateToRoute("job", {id:id}); // ERROR - ROUTE NOT FOUND this.router.navigate("#/job-view/job/".concat(id)); // THIS WORKS } } 

Q.3 : I saw links to router.navigateToRoute and router.navigate , but it wasn’t indicated when to use or what the difference was, and I didn’t see the document to explain What should I use? Docs

Jobs page: Details for jobs.html do not matter, so do not list them here.

Finally, the job view:

Job class: Nothing relevant for job.js , so no code is job.js . In most cases, I can return to jobs , but this is described below on the page.

Job Page:

 <!-- a bunch of html //--> <!-- HOW TO USE ROUTER IN HTML, NOT BELOW URL HREF? //--> <a href="#/jobs">Print Jobs</a> <!-- a bunch of html //--> 

Q.4 : Again, I want the routing to be relative, even on an HTML page. The above will not work, so what should I use?

An answer was offered in a similar question, but entering the job-view in job and using the job-view saved router did not work either.

By the way, if I manually go to http://localhost:3000/#/job-view/job/3 , the page will load normally, so it will clear something with the router.

Note for the mod: A similar question was asked in How to access the child router in Aurelia? but no solution was found that worked.

+6
source share
2 answers

The way to configure child routers in my Aurelia applications is as follows:

 app.js export class App { configureRouter(config, router) { config.map([ { route: ['','home'], name: 'home', moduleId: 'home', nav: true }, { route: 'work', name: 'work', moduleId: 'work/work-section', nav: true }, ]); this.router = router; } } work/work-section.js export class WorkSection { configureRouter(config, router) { config.map([ { route: '', moduleId: './work-list', nav: false }, { route: ':slug', name: 'workDetail', moduleId: './work-detail', nav: false } ]); this.router = router; }; } 

The corresponding "work-section.html" is just looking at the router:

 <template> <router-view></router-view> </template> 

In this case, I have my main app.js, which defines the child router, "work", which is located in a subdirectory under src.

When the /work route is activated, the child router, the "work section", takes over by activating the "work list" route when the path segments end: /work

"work-list.js" retrieves the elements from the REST API, then passes the data to the view. From there, I can use route binding to go to the "work detail" in the "work-list.html" view:

 <div repeat.for="sample of item.samples"> <a route-href="route: workDetail; params.bind: { slug: sample.slug }"> ${sample.title} </a> </div> 

Hope this helps you. I am not 100% sure if you ask how to make a redirect, or how to navigate a children's route from a view, so please correct me if I am wrong and I will do my best to update my answer for you.

+5
source

I will try to answer your questions one by one below.

I will start with Q2

Q.2: Why do we need to keep the router here if it is always accessible from the Aurelia router?

So, in your App App-View App Class, you refer to the router property in your view: <nav-bar router.bind="router"></nav-bar> , so you need to declare the property to use it. In the second view, you don’t need you like that :-)

The router property is also added when you need to do something with the router in main.ts / main.js - the starting point of your application. This is because the router is configured for the first time there, and the injection will not work in the constructor, so you need to save this property in order to get it in the configureRouter(..) method (note: this was before beta 1, t know if he is still there now).

In your code, you have a call for this.router.refreshNavigation(); This will ensure that your router is updated with new routing location information.

Q.3: I saw both router.navigateToRoute and router.navigate links, but there is no indication when to use either what the difference is, and the document did not see to explain. What should i use? Documentation

The router.navigate(fragment: string, options?: any) method uses a fragment of the URL and not the name of the route for navigation, for example, for example. router.navigate('#/app/child', {...<options - not params od the URL>...}) . This method should be used to navigate absolutely between routers, as well as to access the parent URL, etc.

If you are just navigating the current router, you will always use router.navigateToRoute(route: string, params?: any, options?: any) . This method uses the name of the route, not the URL, and we simply specify the name of the route on the user routing map (custom means the current routing map of the child or the current main routing relative to the location of the URL that we find on the page). Here you can pass the URL parameters in a more convenient way, as you can see. You can use the params object instead of concatenating the URL with parameters.

Q.4: Again, I want the routing to be relative, even on an HTML page. The above will not work, so what should I use?

In Aurelia, we do not use the href attribute of the a tag directly for navigation. As Brandon already answered, you should use the route-href attribute, which is probably not documented anywhere, just appears on forums and portals. This is equivalent to router.navigateToRoute(route: string, params?: any, options?: any) , so you cannot use it to navigate between routers, in this case you can use your own attribute or just use click.triger="navTo('#/app/child')" , where the navTo() method is implemented in your View model and looks like this:

 public navTo(routeName: string) { // Assuming you are injecting router somewhere in the constructor this.router.navigateToRoute(routeName); } 

And finally, your question:

Q.1: How to navigate between child routes

You probably know the answer now, just use: router.navigate(fragment: string, options?: any) with an absolute URL.

The following is an example of a custom attribute to solve this problem:

 import {inject} from "aurelia-dependency-injection"; import {Router} from "aurelia-router"; import {customAttribute} from "aurelia-framework"; @customAttribute('nav-href') @inject(Element, Router) export class NavHref { private value: string = ''; constructor(private element: Element, private router: Router) { let $this = this; element.addEventListener('click', () => { if ($this.value === 'back') { $this.router.navigateBack(); } else { // expression $this.router.navigate($this.value); } }); } public valueChanged(newValue: string, oldValue: string) { this.value = newValue; } } 

First you need to import it into your HTML, I named my nav.href.ts file:

 <require from="common/nav.href"></require> 

Then just use it in your HTML code:

 <a nav-href="#/home/any-location">My link to any location</a> 

Hope this helps you, welcome :-)

+2
source

All Articles