英文:
Is it possible to pass @Input object to a component using content projection in Angular?
问题
以下是翻译好的部分:
在 app.component 中,我想要做类似以下的操作:
<app-table-container [data]="tableData">
<app-some-table></app-some-table>
</app-table-container>
table-container.component.html 中:
<!-- 还需要 data-object 的其他内容 -->
<ng-content [data]="data"></ng-content>
table-container.component.ts 中:
@Input() data: ITableStuff;
some-table.component.ts 中:
@Input() data: ITableStuff;
但这个方法不起作用。
我可以将 tableData 传递给 app.component 中的两者,但我想仅将其传递给 table-container,然后再传递给投影内容。
英文:
I want to do something like this in app.component:
<app-table-container [data]="tableData">
<app-some-table></app-some-table>
</app-table-container>
table-container.component.html
<!-- stuff that also needs data-object -->
<ng-content [data]="data"></ng-content>
table-container.component.ts
@Input() data: ITableStuff;
some-table.component.ts
@Input() data: ITableStuff;
This doesn't work
I can pass the tableData to both in app.component but I'd like to pass it only to table-container and from there to projected content.
答案1
得分: 1
在app-some-table的构造函数中,您可以使用以下方式来访问父级并使用getter(而不是输入):
get data() {
return this.tableComponent ? this.tableComponent.data : null;
}
constructor(@Host() @Optional() private tableComponent: AppTableComponent) {}
您还可以在ngAfterViewInit中使用getter来分配值:
export class ChildComponent implements AfterViewInit {
data!: any;
constructor(@Host() @Optional() private tableComponent: ParentComponent) {}
ngAfterViewInit() {
this.data = this.tableComponent ? this.tableComponent.data : null;
}
}
另一种方法是使用ContentChild。在父组件中,您可以这样设置:
@ContentChild(ChildComponent) child!: ChildComponent;
然后在ngAfterViewInit中,可以这样做:
ngAfterViewInit() {
setTimeout(() => {
if (this.child)
this.child.anotherData = this.data;
});
}
请注意,这种方法需要知道"childComponent"类。您可以始终从一个组件基类扩展所有可能的子组件,并询问"ChildComponentBase"。
英文:
You can "reach" the parent using in constructor of app-some-table and use a getter (not an input)
get data()
{
return this.tableComponent?this.tableComponent.data:null
}
constructor(@Host() @Optional() private tableComponent:AppTableComponent){}
You can also, instead use a getter assign the value in ngAfterViewOnInit
export class ChildComponent implements AfterViewInit{
data!:any
constructor(@Host() @Optional() private tableComponent:ParentComponent){}
ngAfterViewInit()
{
this.data=this.tableComponent?this.tableComponent.data:null
}
}
See stackblitz (in the stackblitz is the second option, I enclosed in a setTimeout when equal the data to avoid the error "Expression has changed after it was checked")
Update another approach is use ContentChild.
In our parent
@ContentChild(ChildComponent) child!:ChildComponent
And in ngAfterViewInit
ngAfterViewInit()
{
setTimeout(()=>{
if (this.child)
this.child.anotherData=this.data
})
}
But this approach need know the "childComponent" class. Always can extends all the possibles child from a component base and ask about "ChildComponentBase"
答案2
得分: 0
以下是要翻译的内容:
这不是一件容易的事情,因为在这种情况下存在DI层次结构。
一种选择是使用 ContentChild
/ContentChildren
来获取 some-table.component
的实例,并在 AfterContentInit
回调中分配其输入。
英文:
It is not straightforward because of DI hierarchy in this case.
One option is to use ContentChild
/ContentChildren
to get instance of some-table.component and assign its input in AfterContentInit
callback.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论