Typescript 如何根据当前路由应用条件类属性?

Typescript 如何根据当前路由应用条件类属性?,typescript,aurelia,Typescript,Aurelia,我的应用程序中有一个导航组件,它有几个指向不同页面的链接,可以通过路由访问这些页面。如果路由器当前位于链接引用的同一页面上,我想将导航项显示为“活动”。我尝试了几种方法,最后得到了以下代码,根据当前路线动态设置CSS类: 模板: 视图模型: 这段代码确实如预期的那样工作。我的问题是,我需要找到一个更具动态性的解决方案,因为这个解决方案无法扩展。目前,我必须为需要实现的每个导航项添加一个getter 我试图使用函数而不是getter,但问题是在所有情况下,this.router.c

我的应用程序中有一个导航组件,它有几个指向不同页面的链接,可以通过路由访问这些页面。如果路由器当前位于链接引用的同一页面上,我想将导航项显示为“活动”。我尝试了几种方法,最后得到了以下代码,根据当前路线动态设置CSS类:

模板:


视图模型:

这段代码确实如预期的那样工作。我的问题是,我需要找到一个更具动态性的解决方案,因为这个解决方案无法扩展。目前,我必须为需要实现的每个导航项添加一个getter

我试图使用函数而不是getter,但问题是在所有情况下,
this.router.currentInstruction
的值都为null

有没有一种有效的方法来实现带有参数的函数,这样我就可以从模板中绑定它,而不必为每个链接添加函数或getter


非常感谢您的帮助。

我使用了一个自定义属性:

//is-active.js

import { Router } from 'aurelia-router';
import { EventAggregator } from 'aurelia-event-aggregator';
import { inject, customAttribute, DOM, bindable } from 'aurelia-framework';

const EVENT_NAME = 'router:navigation:success';

@inject(DOM.Element, Router, EventAggregator)
@customAttribute('is-active')
@bindable({ name: 'route' })
@bindable({ name: 'selector', defaultValue: 'is-active' })
export class IsActiveCustomAttribute {

    constructor(element, router, eventAggregator) {
        this.router = router;
        this.element = element;
        this.ea = eventAggregator;
    }

    attached() {
        this.subscriber = this.ea.subscribe(EVENT_NAME, this.handler.bind(this));
    }

    detached() {
        this.subscriber.dispose();
    }

    handler() {
        let config = this.router.currentInstruction.config;
        let currentRoute = config.name;
        let hasSelector = this.element.classList.contains(this.selector);
        let matchChildren = config.route.split('/', 1)[0] === this.route;

        if (this.route === currentRoute || matchChildren) {
            if (!hasSelector) {
                this.element.classList.add(this.selector);
            }
        } else if (hasSelector) {
            this.element.classList.remove(this.selector);
        }
    }
}
//html

<nav class="mdl-navigation mdl-layout--large-screen-only">
    <a class="mdl-navigation__link" 
        is-active="route: courses" 
        route-href="route: courses">Courses</a>

    <a class="mdl-navigation__link" 
        is-active="route: freebies" 
        route-href="route: freebies">Freebies</a>

    <a class="mdl-navigation__link" 
        is-active="route: blog" 
        route-href="route: blog">Blog</a>
</nav>

我使用了一个自定义属性:

//is-active.js

import { Router } from 'aurelia-router';
import { EventAggregator } from 'aurelia-event-aggregator';
import { inject, customAttribute, DOM, bindable } from 'aurelia-framework';

const EVENT_NAME = 'router:navigation:success';

@inject(DOM.Element, Router, EventAggregator)
@customAttribute('is-active')
@bindable({ name: 'route' })
@bindable({ name: 'selector', defaultValue: 'is-active' })
export class IsActiveCustomAttribute {

    constructor(element, router, eventAggregator) {
        this.router = router;
        this.element = element;
        this.ea = eventAggregator;
    }

    attached() {
        this.subscriber = this.ea.subscribe(EVENT_NAME, this.handler.bind(this));
    }

    detached() {
        this.subscriber.dispose();
    }

    handler() {
        let config = this.router.currentInstruction.config;
        let currentRoute = config.name;
        let hasSelector = this.element.classList.contains(this.selector);
        let matchChildren = config.route.split('/', 1)[0] === this.route;

        if (this.route === currentRoute || matchChildren) {
            if (!hasSelector) {
                this.element.classList.add(this.selector);
            }
        } else if (hasSelector) {
            this.element.classList.remove(this.selector);
        }
    }
}
//html

<nav class="mdl-navigation mdl-layout--large-screen-only">
    <a class="mdl-navigation__link" 
        is-active="route: courses" 
        route-href="route: courses">Courses</a>

    <a class="mdl-navigation__link" 
        is-active="route: freebies" 
        route-href="route: freebies">Freebies</a>

    <a class="mdl-navigation__link" 
        is-active="route: blog" 
        route-href="route: blog">Blog</a>
</nav>

您可以使用内置方式检查您所在的路线是否为活动路线。Aurelia router已经为您提供了此属性。如果您不想将某些路线添加到UI中,则可以使用路线定义中的
nav
属性,并将其设置为
false
,这样就不会将其添加到
route.navigation
数组中

就像这个例子:

路由器配置

 { route: 'users',            name: 'users',      moduleId: 'users/index',   nav: true },
  { route: 'users/:id/detail', name: 'userDetail', moduleId: 'users/detail' },
您想在哪里显示菜单

<li repeat.for="row of router.navigation" class="${row.isActive ? 'active' : ''}">

  • 您可以使用内置方式检查您所在的路线是否为活动路线。Aurelia router已经为您提供了此属性。如果您不想将某些路线添加到UI中,则可以使用路线定义中的
    nav
    属性,并将其设置为
    false
    ,这样就不会将其添加到
    route.navigation
    数组中

    就像这个例子:

    路由器配置

     { route: 'users',            name: 'users',      moduleId: 'users/index',   nav: true },
      { route: 'users/:id/detail', name: 'userDetail', moduleId: 'users/detail' },
    
    您想在哪里显示菜单

    <li repeat.for="row of router.navigation" class="${row.isActive ? 'active' : ''}">
    

  • 这正是我想要的。值得一提的是,您可以使用“href”属性访问URL,并且可以使用“title”属性指定显示名称。“href”属性不需要手动设置,如果指定,则从“route”属性获取其值。我的最终解决方案是这样的:
  • 这正是我想要的。值得一提的是,您可以使用“href”属性访问URL,并且可以使用“title”属性指定显示名称。“href”属性不需要手动设置,如果指定,则从“route”属性获取其值。我的最终解决方案是这样的:
  • 谢谢您的回答。我相信这是可行的,我想你可以在生产中使用它。但对我来说,来自@maximedubois的答案正是我想要的。这个解决方案似乎是使用框架做“艰苦工作”的方法。谢谢你的回答。我相信这是可行的,我想你可以在生产中使用它。但对我来说,来自@maximedubois的答案正是我想要的。这个解决方案似乎是使用该框架进行“艰苦工作”的方法。