将上下文传递给 Angular 2 组件的投影内容(使用 ng-content)
Posted
技术标签:
【中文标题】将上下文传递给 Angular 2 组件的投影内容(使用 ng-content)【英文标题】:Passing context to an Angular 2 component's projected content (using ng-content) 【发布时间】:2016-10-24 09:01:43 【问题描述】:我正在编写一个可重用的 Angular 2 组件来检索和显示表格中的数据,以及服务器端排序、过滤和搜索。我希望表中的每一行都有一个额外的列,其中包含使用 ng-context 标记的通用 html,我可以做到这一点。
最常见的情况是有按钮可以使用构建每行的数据执行操作(例如,导航到条目的特定页面,或删除条目),但似乎没有是一种将对象传递给组件的 ContentChildren 的方法。我也许可以通过直接的 DOM 操作和检查来实现这一点,但这既非常笨拙,也不利于可重用性。
我并不真正关心实现这一点的任何具体方法,只要它:
允许我将通用 html 添加为组件的子组件 可以将一些通用数据从父组件传递到其 ContentChildren(前面提到的通用 html),以便子组件的事件处理程序可以使用这些数据。我正在使用 typescript,因此首选类型安全的解决方案,但如果需要,我很乐意忽略类型系统。
我使用的表格组件(my-table)看起来像
<my-table /* some properties */>
<button class="row-button" type="button" (click)="navigate(/* context */)">Navigate</button>
</my-table>
使用 ng-content 的模板如下:
// table html
<tr *ngFor="let row of rows">
<td *ngFor="let column of row.columns">column</td>
<td>
<ng-content select=".row-button"></ng-content>
</td>
</tr>
// more table html
如果我可以向 ng-content 传递一个参数,该参数可由按钮元素使用就足够了。
【问题讨论】:
如果您可以添加一些代码来显示您尝试完成的具体示例,这将有所帮助。 “上下文”是怎样的?它从何而来?它应该在哪里可用?如果 X 发生,什么确切的属性应该发生什么。 我添加了一些伪代码,尽管我对实现它的实际方式持矛盾态度。 “上下文”只是一个对象,它来自父级,并且可以在子级的模板中使用(或者我可以完成它) 什么是“父”?<my-table>
是模板中包含第一个代码sn-p的父级还是组件。在后一种情况下,如果父级在组件类中有 content
属性,这应该可以工作。
如果您对使用 ng-content 不严格,ng-template
可以完成这项工作:
<my-table [rowButtonTemplate]="buttonTemplate" /* some properties */>
<ng-template #buttonTemplate let-column>
<button class="row-button" type="button" (click)="navigate(column.context)">Navigate</button>
</ng-template>
</my-table>
然后在表内:
// table ts
@Input()
rowButtonTemplate: TemplateRef;
// table html
<tr *ngFor="let row of rows">
<td *ngFor="let column of row.columns">column</td>
<td>
<ng-container *ngTemplateOutlet="rowButtonTemplate; context: $implicit: column, index: index "></ng-container>
</td>
</tr>
// more table html
【讨论】:
这是唯一对我有用的东西。尝试:将项目内容转换为模板 |项目内容模板| ...(与 ViewChild、ContentChild、ngContainer、ngContent 的 X 组合)。疯狂的是,Angular 无法单独提供内容投影。【参考方案2】:一种方法是使用允许您显式引用父级的模板变量:
<my-table #myTable>
<button [context]="myTable.context">
</my-table>
据我所知,有计划使其更加灵活。我猜是这个问题https://github.com/angular/angular/issues/8563
【讨论】:
此解决方案不允许我传入每一行的数据。如果无法访问行上的循环的索引,我无法将正确的行传递给孩子。不过,我可以看到它会如何正常工作,我会密切关注这个问题。 我明白你的意思了。我以前没有看到。在*ngFor
中添加<ng-content>
无论如何都不起作用。一切都将被嵌入到带有匹配选择器的第一个 <ng-content>
标记中。
计划增加对这个用例的支持,但我不知道这可能需要多长时间才能落地。我认为这是要关注的问题github.com/angular/angular/issues/8563以上是关于将上下文传递给 Angular 2 组件的投影内容(使用 ng-content)的主要内容,如果未能解决你的问题,请参考以下文章