Angular 2 Child Routes未按预期工作

时间:2016-05-04 15:15:36

标签: routing angular parent-child

我使用A2的路由器(angular2@2.0.0-beta.13)获得了一个应用程序,我正在努力让孩子们的路线正常工作但却变得奇怪了。当应用程序加载时,开发窗口中的结构如下所示:

<application>
    <router-outlet></router-outlet>
    <undefined>
        <div class="metrics-header">...</div>
        <router-outlet></router-outlet>
        <undefined>
            <div class="metrics-header">...</div>
            <router-outlet></router-outlet>
            <div class="metrics-footer">...</div>
        </undefined>
        <div class="metrics-footer">...</div>
    </undefined>
<application>

ApplicationComponent(Parent):

import {Component, EventEmitter} from 'angular2/core';
import {Router, RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS,
        LocationStrategy, HashLocationStrategy} from 'angular2/router';

import {LoginComponent} from '../login/login.component';
import {MetricsComponent} from '../metrics/metrics.component';

import {EmitterService} from '../../services/emitter/emitter.service';

@Component({
    selector:'application',
    styleUrls:['./app/components/application/application.component.css'],
    templateUrl:'./app/components/application/application.component.html',
    directives:[ROUTER_DIRECTIVES],
    providers:[ROUTER_PROVIDERS, EmitterService]
})

@RouteConfig([
    {path:'../login', name:'Login', component:LoginComponent},
    {path:'../metrics/...', name:'Metrics', component:MetricsComponent, useAsDefault:true}
    ])

export class ApplicationComponent{

    emitter = EmitterService.get("LoginChannel");

    constructor(
        private _router: Router
    ){
        this.emitter.subscribe(data => this.navigateTo(data));
    }

    navigateTo(view){
        console.log('navigateTo(' + view + ')');
        this._router.navigate([view]);
    }
}

ApplicationComponent模板:

<router-outlet></router-outlet>

MetricsComponent(Child):

import {Component, OnInit, Input, EventEmitter} from 'angular2/core';
import {Router, RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS} from 'angular2/router';
import {Subscription}   from 'rxjs/Subscription';

import {TouchGesturesService} from '../../services/touch-gestures/touch-gestures.service';
import {MetricsService} from '../../services/metrics/metrics.service';
import {EmitterService} from '../../services/emitter/emitter.service';

import {DatacardsComponent} from '../datacards/datacards.component';

@Component({
    styleUrls:['./app/components/metrics/metrics.component.css'],
    templateUrl:'./app/components/metrics/metrics.component.html',
    providers: [EmitterService, MetricsService, TouchGesturesService, ROUTER_PROVIDERS, EmitterService],
    directives:[DatacardsComponent, ROUTER_DIRECTIVES],
})

@RouteConfig([
    { path: '/pastYear', name: 'PastYear', component: DatacardsComponent, useAsDefault: true },
    { path: '/pastMonth', name: 'PastMonth', component: DatacardsComponent },
    { path: '/dailyAverage', name: 'DailyAverage', component: DatacardsComponent },
])

export class MetricsComponent implements OnInit{

    emitter = EmitterService.get('LoginChannel');

    subscription: Subscription;

    public pages = ['Past Year', 'Past Month', 'Daily Average'];
    public currentPage = 0;

    startCoords = { x: null, y: null };
    currentCoords = { x: null, y: null };
    endCoords = { x: null, y: null, swipe: null };

    screen = { w: null, h: null };

    constructor(
        private _touchGesturesService: TouchGesturesService,
        private _router: Router
    ){
        this.screen = {
            w: window.innerWidth,
            h: window.innerHeight
        }
        console.log('Window Width: ' + this.screen.w);
        console.log('Window Height: ' + this.screen.h);
        this.swipeMetrics(null);
    }

    swipeMetrics(swipeDirection){
        switch (swipeDirection) {
            case 'left':
                console.log('swiping left');
                console.log('incoming view: ' + this.pages[this.currentPage].replace(' ', ''))
                this._router.navigate([this.pages[this.currentPage].replace(' ', '')]);
                break;
            case 'right':
                console.log('swiping right');
                console.log('incoming view: ' + this.pages[this.currentPage].replace(' ', ''))
                this._router.navigate([this.pages[this.currentPage].replace(' ', '')]);
                break;
            default:
                //console.log('not swiping');
                break;
        }
    }

    ngOnInit(){
    }

    swipeStart(){
        this.startCoords = this._touchGesturesService.swipeStart();
        //console.log('startCoords: ' + this.startCoords.x + ' | ' + this.startCoords.y);
    }
    swipeMove(){
        this.currentCoords = this._touchGesturesService.swipeMove();
        //console.log('currentCoords: ' + this.currentCoords.x + ' | ' + this.currentCoords.y);
    }
    swipeEnd(){
        this.endCoords = this._touchGesturesService.swipeEnd();
        var cp = this.currentPage;
        //console.log('swiped ' + this.endCoords.swipe.direction);
        switch (this.endCoords.swipe.direction) {
            case 'left':
                cp++;
                if(cp < this.pages.length){
                    this.currentPage = cp;
                }else{
                    //console.log('reset currentPage to 0');
                    this.currentPage = 0;
                }
                //console.log('currentPage: ' + this.currentPage);
                this.swipeMetrics('left');
                break;
            case 'right':
                cp--;
                if(cp < 0){
                    //console.log('reset currentPage to ' + (this.pages.length - 1));
                    this.currentPage = this.pages.length - 1;
                }else{
                    this.currentPage = cp;
                }
                //console.log('currentPage: ' + this.currentPage);
                this.swipeMetrics('right');
                break;
        }
        //console.log('endCoords: ' + this.endCoords.x + ' | ' + this.endCoords.y + ' (' + this.endCoords.swipe.direction + ')');
    }

    isCurrentPage(page){
        return (page === this.currentPage) ? true : false;
    }

    reload(){
        window.location.href = '/application-starter-kit/src';
    }

    logout(){
        // need logoout functionality after login is fully implemented
        this.emitter.emit('Login');
    }
}

MetricsComponent模板:

    <div class="metrics-header">
        <div (click)="logout()">Logout</div>
        <div>{{ pages[currentPage] }}</div>
        <div><a (click)="reload()">Reload</a></div>
    </div>
    <router-outlet></router-outlet>
    <div class="metrics-footer">
        <div></div>
        <div class="current-page">
            <div *ngFor="#page of pages; #i=index" [class.selected]="isCurrentPage(i)"></div>
        </div>
        <div></div>
    </div>

另一个注意事项:由于目前应用程序的结构,我必须在父RouteConfig上使用../才能使用。

1 个答案:

答案 0 :(得分:1)

删除路径前面的..

@RouteConfig([
    {path:'/login', name:'Login', component:LoginComponent},
    {path:'/metrics/...', name:'Metrics', component:MetricsComponent, useAsDefault:true}
    ])

并为子路线添加/

@RouteConfig([
    { path: '/pastYear', name: 'PastYear', component: DatacardsComponent, useAsDefault: true },
    { path: '/pastMonth', name: 'PastMonth', component: DatacardsComponent },
    { path: '/dailyAverage', name: 'DailyAverage', component: DatacardsComponent },
])

Angular2路由器是分层的,对于当前路由器,路径是根级路径。