Aurelia: How navigate between child routes

梦想的初衷 提交于 2019-12-03 15:25:34

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

I will start from Q2

Q.2: Why do we need to save router here if it's always accessible from aurelia-router?

So in your App Mode-View App Class you are referencing router property in your view: <nav-bar router.bind="router"></nav-bar>, that's why you need to declare the property to use it then. In the second view you are not so you don't need it :-)

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

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

Q.3: I've seen both router.navigateToRoute and router.navigate referenced, but no indication when to use either or what the difference is, and the document doesn't seen to explain. Which should be used? Docs

The method router.navigate(fragment: string, options?: any) uses an URL fragment not a route name to navigate, so e.g. router.navigate('#/app/child', {...<options - not params od the URL>...}). This method must be used to navigate absolutely between routers, and to access parent URL etc.

If you only are navigating around the current router you will always use router.navigateToRoute(route: string, params?: any, options?: any). This method is using a route name, not URL, co we just put there a name of route in the custom routing map (custom means the current child routing map, or current main routing regarding the URL location we are on the page). Here you can pass URL params in more convenient way, as you can see. You can use a params object instead of concatenating the URL with params.

Q.4: Again, I'd like routing to relative, even in the HTML page. The above won't work, so what should I use?

In Aurelia we are not using href attribute of the a tag directly for navigation. As already answered by Brandon, you have to use route-href attribute, which is probably nowhere documented just appears around on forums and portals. This is equivalent of the router.navigateToRoute(route: string, params?: any, options?: any), so you cannot use it to navigate between routers in such case you can use custom 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 topic question:

Q.1: How navigate between child routes

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

Below example custom attribute to solve this:

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 in your HTML, I named my file nav.href.ts:

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

Then just use it in you HTML code:

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

Hope this will help you, cheers :-)

The way I've configured child routers in my Aurelia apps is in this fashion:

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 simply a Router View:

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

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

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

"work-list.js" retrieves items from a REST API then passes the data to the view. From there, I'm able to use route binding to get to a "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 that helps you out. I'm not 100% certain if you're asking how to do a redirect, or how to nav to a child route from the view, so please correct me if I'm wrong and I'll do my best to update my answer for you.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!