如何在 Angular2 中操作特定路径上的组件

2023-11-24

我有一个简单的TopbarComponent这基本上在我的视图顶部添加了一个引导式导航栏。

由于我的 90% 的模板应该包含这个指令,我想通过我的app.component看起来像这样:

import ...;

@Component({
    selector: 'my-app',
    templateUrl: 'app/app.component.html',
    directives: [ROUTER_DIRECTIVES, TopbarComponent, ...],
    providers: [ROUTER_PROVIDERS, ...]
})

@RouteConfig([
{
    path: '/login',
    name: 'Login',
    component: LoginComponent
},
{
    path: '/dashboard',
    name: 'Dashboard',
    component: DashboardComponent,
    useAsDefault: true
}
])

它的模板如下所示:

<my-topbar></my-topbar>

<div class="container-fluid">
    <div class="row">
        <router-outlet></router-outlet>
    </div>
</div>

现在我想用ngIf(或者除了用CSS隐藏它之外的任何其他方式)隐藏多个路线上的顶栏,例如/login例如。 我尝试了几种方法使用@CanAcitvate()或实施OnActivate in my LoginComponent(以及从我的尝试AppComponent)但没有任何效果(甚至无法启动功能)。 我得到的最接近的是使用Router直接在我的AppComponent像这样:

export class AppComponent implements OnInit{
    showTopbar:boolean;

    constructor(private _router:Router) {}

    ngOnInit():any {
        this.showTopbar = this._router.lastNavigationAttempt != '/login';
    }
}

并在我的app.component.html我将指令更改为<my-topbar *ngIf="showTopbar"></my-topbar>

但这仅适用于我的应用程序的初始加载,因为ngOnInit不会在每次状态更改时触发。我是否可以使用类似的方法(只是找不到)或者我在这里朝错误的方向前进?


Edit:

目前,PierreDuc 的答案对我不起作用,但我尝试使用类似的方法location.path()像这样:

constructor(private _location:Location) {}

private get _hideTopbar() : boolean {
    switch(this._location.path()){
        case '/register':
        case '/login':
            return true;
        default:
            return false;
    }
};

可惜我不能使用data财产在@RouteConfig在这种方法中。感觉会好一些。


一段时间以来,我一直在为类似的问题而苦恼。 我找到的解决方案一开始可能会被认为很棘手,但将来可以为我解决许多类似的此类问题。

基本上,你必须做router-outlet在路线改变时发出一个事件,让你的AppComponent监听该自定义事件。

第一步是创建一个自定义路由器出口:

@Directive({
selector: 'custom-router-outlet'
})
export class CustomRouterOutlet extends RouterOutlet {
    private parentRouter:Router;

    constructor(_elementRef: ElementRef,
            _loader: DynamicComponentLoader,
            _parentRouter: Router,
            @Attribute('name') nameAttr: string) {
    super(_elementRef, _loader, _parentRouter, nameAttr);
    this.parentRouter = _parentRouter;
    }

    activate(nextInstruction: ComponentInstruction): Promise<any> {
        //***YOUR CUSTOM LOGIC HERE***
        return super.activate(nextInstruction);
    }
}

这是自定义路由器出口的非常基本的实现。你的逻辑必须在activate方法,在每次路线更改时调用。 在此方法中,您可以检查路线中的数据属性。

现在主要的问题是,指令无法发出事件...它们只接受输入,不能触发输出...

我找到了解决此问题的方法:创建一个Service用于组件和指令之间的通信使用EventEmitter:

@Injectable()
export class PubsubService {
    private _pubSubber: EventEmitter<any> = new EventEmitter();

    routeisChanging(obj:any) {
        this._pubSubber.emit(obj);
    }

    onRouteChanged() {
        return this._pubSubber;
    }
}

The 应用组件订阅了onRouteChanged event:

subscription:any;
constructor(private _pubsubService:PubsubService) {
    this.subscription = this._pubsubService.onRouteChanged().subscribe(data => {
        /**YOUR CUSTOM LOGIC HERE*/});
}

The 自定义路由器插座触发事件activate需要时的方法:

activate(nextInstruction: ComponentInstruction): Promise<any> {
    //***YOUR CUSTOM LOGIC HERE***
    this._pubsubService.routeisChanging(nextInstruction.routeData.data['hideTopbar']);
    return super.activate(nextInstruction);
}

这样就可以轻松实现路由器与路由器之间的通信了AppComponent,与任何逻辑。

你必须记住将通信服务注入RootComponent您的应用程序的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Angular2 中操作特定路径上的组件 的相关文章

随机推荐