2016-05-15 82 views
1

我有一個父組件,它從路由參數中獲取一個id值。我想將它傳遞給子組件,所以我通過子組件上的Input()裝飾器來完成此操作。但是,我無法將路由參數值傳遞給孩子。如果我對一個值進行硬編碼並將其傳遞給它的子元素,那麼我相信綁定和子元素邏輯是可以的;我認爲這只是一個動態設置值的方式/問題。將路由參數傳遞給Angular 2中的子組件作爲輸入

這裏的一些意見充分父組件:

import { Component }            from '@angular/core'; 
import { HTTP_PROVIDERS }           from '@angular/http'; 
import { provide }             from '@angular/core'; 
import { Routes, Router, RouterUrlSerializer, ROUTER_DIRECTIVES } from '@angular/router'; 
import { Location }             from '@angular/common'; 
import { XHRBackend }            from '@angular/http'; 

import { ContentNode }            from './content-node'; 
import { ContentTreeComponent }          from './content-tree.component'; 
import { ContentDashboardComponent }        from './content-dashboard.component'; 
import { ContentEditComponent }          from './content-edit.component'; 

import { ContentService }           from '../services/content.service'; 
import { InitService }            from '../services/init.service'; 
import { RouteNames }            from '../services/route-names.service'; 

@Component({ 
    selector: 'my-dashboard', 
    template: ` 
     <div class="tree-panel-container"> 
      <div class="tree-panel-content"> 
       <content-tree [startNodeId]="startNodeIdContent" [currentNodeId]="currentNodeId"></content-tree> 
      </div> 
     </div> 
     <router-outlet></router-outlet> 
    `, 
    directives: [ 
     ContentTreeComponent, 
     ContentDashboardComponent, 
     ROUTER_DIRECTIVES 
    ], 
    providers: [ 
     HTTP_PROVIDERS 
    ] 
}) 
@Routes([ 
    { path:'/', component: ContentDashboardComponent }, 
    { path:'/:id', component: ContentEditComponent } 
]) 
export class ContentComponent { 

    _currentNodeId: number; 

    constructor(private router:Router, private routeSerializer:RouterUrlSerializer, private location:Location) { 
     router.changes.first().subscribe(() => { 
      let urlTree = this.routeSerializer.parse(location.path()); 
      let urlSegment = urlTree.children(urlTree.children(urlTree.root)[0])[0]; 
      if(urlSegment != undefined){ 
       let id = urlSegment.segment; 
       this._currentNodeId = id; 
       console.log('_currentNodeId', this._currentNodeId); // This works - it logs the correct id from the route param 
      } 
     }); 
    } 

    startNodeIdContent = InitService.startNodeIdContent; 
    currentNodeId = this._currentNodeId; // This doesn't work - it just results in 'undefined' in the child component 

    // The following line works; it passes 123 to the child component, so I know the binding and the child input is set up correctly: 
    // currentNodeId = 123; 
} 

...這是子組件:

import { Component, Input, OnInit }   from '@angular/core'; 
import { Router, RouteSegment, RouteTree } from '@angular/router'; 

import { ContentNode }      from './content-node'; 
import { ContentService }     from '../services/content.service'; 


@Component({ 
    selector: 'content-tree', 
    directives: [ContentTreeComponent], 
    template: ` 
     <ol class="tree"> 
      <li *ngFor="let contentNode of contentNodes" class="tree__branch" [ngClass]="{'tree__branch--has-children': contentNode.HasChildren}"> 
       <a *ngIf="contentNode.HasChildren" (click)="contentNode.toggle=!contentNode.toggle" class="tree__branch__toggle"> 
        {{ !!contentNode.toggle ? '-' : '+' }} 
       </a> 
       <a class="tree__branch__link" (click)="onSelect(contentNode)">{{ contentNode.Name }}</a> 
       <content-tree *ngIf="contentNode.toggle" [startNodeId]="contentNode.Id"></content-tree> 
      </li> 
     </ol> 
     <div class="error" *ngIf="errorMessage">{{errorMessage}}</div> 
     <p>{{test}}</p> 
    ` 
}) 
export class ContentTreeComponent implements OnInit { 

    constructor(
     private _contentService: ContentService, 
     private _router: Router, 
     private _currSegment: RouteSegment 
    ) { } 

    errorMessage: string; 

    @Input('startNodeId') 
    private _startNodeId: number; 

    @Input('currentNodeId') 
    private _currentNodeId: number; 

    contentNodes: ContentNode[]; 

    ngOnInit() { 
     this.getContentNodes(); 

     console.log('_startNodeId = ' + this._startNodeId); 
     console.log('_currentNodeId = ' + this._currentNodeId); 
    } 

    onSelect(contentNode: ContentNode) { 
     this._router.navigate([`./${contentNode.Id}`], this._currSegment); 
    } 

    getContentNodes() { 
     this._contentService.getContentNodes(this._startNodeId) 
      .subscribe(
       contentNodes => this.contentNodes = contentNodes, 
       error => this.errorMessage = <any>error 
      ); 
    } 
} 
+0

您可以請添加子組件也 –

+1

btw您應該注入您的InitService在構造函數中,如構造函數(InitService _initService,......),並調用函數 startNodeIdContent = _initService.startNodeIdContent; –

+0

(更新了包含子組件的問題) – Dan

回答

1

路由器使用ViewContainerRef.createComponent添加組件。對於以此方式添加的組件@Input()@Output()不受支持。

在不支持輸入和輸出的組件之間共享數據的常見方式是共享服務。欲瞭解更多詳細信息,請參閱https://angular.io/docs/ts/latest/cookbook/component-communication.html

+0

很高興知道,謝謝Günter。我將繼續提供服務。 – Dan

1

我有同樣的問題,當我嘗試傳遞任何值,而我路由到子組件,所以它似乎不工作,因爲路由器將ViewContainerRef.createComponent添加到這些子組件,所以@輸入和@Output不會工作, 我做了SharedService並在父組件中啓動它,並在需要它的地方注入此服務。希望它也能幫助你

相關問題