我有一个父组件,它从路由参数中获取一个id值。我想将它传递给子组件,所以我通过子组件上的Input()
装饰器来做这件事。但是,我无法将路线参数值传递给孩子。如果我对一个值进行硬编码并将其传递给它可以正常工作,那么我相信绑定和子组件逻辑是可以的;我认为这只是我如何/在哪里动态设置值的问题。
这是包含一些注释的完整父组件:
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)
路由器使用ViewContainerRef.createComponent
添加组件。对于以这种方式添加的组件,不支持@Input()
和@Output()
。
在不支持输入和输出的组件之间共享数据的常用方法是共享服务。有关详细信息,请参阅https://angular.io/docs/ts/latest/cookbook/component-communication.html
答案 1 :(得分:1)
当我在路由到子组件时尝试传递任何值时遇到了同样的问题,所以它似乎不起作用,因为路由器将ViewContainerRef.createComponent添加到那些子组件,因此@Input和@Output都不会工作, 我创建了SharedService并在父组件中启动它并在我需要的地方注入了这个服务。希望它也能帮助你
答案 2 :(得分:0)
我创建了一个小型库(目前仅适用于angular 9,我可能可以添加对较早版本的支持,但还会附带一些其他代码)
npm install --save ngx-route-params-input
您可以在此处查看它的运行情况: https://stackblitz.com/edit/angular-v8hdug?embed=1&file=src/app/user/user-routing.module.ts
它正在以另一种方式工作:
// import component (you will also need to provide
// NgxRouteParamsInputModule to your angular module imports)
import { NgxRouteParamsInputComponent } from "ngx-route-params-input";
const routes: Routes = [
{
path: ":userId",
// Change YourComponent to NgxRouteParamsInputComponent:
component: NgxRouteParamsInputComponent,
data: {
// Provide YourComponent in route data
component: YourComponent,
// Provide params you want to pass from URL to component
routeParams: {
userId: "userId"
},
// you can also provide query params
queryParams: {
content: "content"
}
}
}
];
如果对此包有任何问题或评论,请随时在GitHub上添加评论/功能请求等(您可以在npm网站上找到它和文档)