扩展 MatRowDef [英] Extending MatRowDef
问题描述
我想在点击时在两行之间显示一些自定义组件/html.我相信快速简便的解决方案是使用来自点击处理程序的事件并直接操作 DOM,但是如果可能的话,我想以角度方式来做.
I want to display some custom component/html between two rows on click. I believe the quick and easy solution would be to use the event from the click handler and manipulate the DOM directly however I'd like to do it the angular way if possible.
为了获得灵感,我首先查看了 这篇文章 关于扩展结构指令.但是它的用途有限,因为 *matRowDef
不应该单独使用,而是与其他元素结合作为材料表的一部分使用.然后我去看了源码code 并试图模仿 MatRowDef
扩展 CdkRowDef
的方式并最终得到这个:
For inspiration I first looked at this article on extending structural directive. It was of limited use though since *matRowDef
isn't supposed to be used on its own, but in conjunction with other elements as part of the material table. I then went to have a look at the source code directly and tried to mimic the way MatRowDef
extended CdkRowDef
and ended up with this:
@Directive({
selector: '[expandableRowDef]',
providers: [
{provide: MatRowDef, useExisting: ExpandableRowDirective},
{provide: CdkRowDef, useExisting: ExpandableRowDirective}
],
inputs: ['columns: expandableRowDefColumns', 'when: expandableRowDefWhen']
})
export class ExpandableRowDirective<T> extends MatRowDef<T> {
constructor(template: TemplateRef<any>,
viewContainer: ViewContainerRef,
_differs: IterableDiffers) {
super(template, _differs);
}
}
然后我简单地将 *matRowDef="..."
与 *expandableRowDef="..."
切换,它编译得很好并且在运行时不会失败.
I then simply switched *matRowDef="..."
with *expandableRowDef="..."
, it compiles fine and doesn't fail at runtime.
我应该从哪里开始编辑创建的 mat-row
元素内的 DOM?
Where should I take it from here to edit the DOM inside the created mat-row
element?
推荐答案
不久前我对类似的东西有一个基本的要求,并根据 这个线程.
I had a basic requirement for something similar a while ago, and managed to put something together based off the discussion and broken plunkr on this thread.
它本质上是通过使用 ComponentFactory
<创建自定义组件来工作的/strong> 然后使用 @ViewChildren
获取表格行列表,单击选定的表格行会在指定的 index
处插入自定义组件,使用 @Input
:
It essentially works by creating a custom component using ComponentFactory
and then using @ViewChildren
to get a list of the table rows, and on click of the selected table row inserts the custom component at the specified index
passing in the row data using @Input
:
模板:
<mat-row *matRowDef="let row; columns: displayedColumns; let index = index"
(click)="insertComponent(index)"
#tableRow
matRipple>
</mat-row>
组件:
export class TableBasicExample {
displayedColumns = ['position', 'name', 'weight', 'symbol'];
dataSource = new MatTableDataSource<Element>(ELEMENT_DATA);
@ViewChildren('tableRow', { read: ViewContainerRef }) rowContainers;
expandedRow: number;
constructor(private resolver: ComponentFactoryResolver) { }
insertComponent(index: number) {
if (this.expandedRow != null) {
// clear old content
this.rowContainers.toArray()[this.expandedRow].clear();
}
if (this.expandedRow === index) {
this.expandedRow = null;
} else {
const container = this.rowContainers.toArray()[index];
const factory: ComponentFactory<any> = this.resolver.resolveComponentFactory(InlineMessageComponent);
const inlineComponent = container.createComponent(factory);
inlineComponent.instance.user = this.dataSource.data[index].name;
inlineComponent.instance.weight = this.dataSource.data[index].weight;
this.expandedRow = index;
}
}
}
插入行之间的自定义组件:
Custom component which gets inserted between the rows:
@Component({
selector: 'app-inline-message',
template: 'Name: {{ user }} | Progress {{ progress}}%',
styles: [`...`]
})
export class InlineMessageComponent {
@Input() user: string;
@Input() weight: string;
}
我在 StackBlitz 这里上创建了一个基本的工作演示一>.由于此功能尚未得到官方支持,因此以这种方式执行最终可能会破坏线路,但是 Angular Material 团队确实有类似的东西 正在筹备中.
I have created a basic working demo of this on StackBlitz here. Since this functionality is not officially supported yet, doing it in this way may eventually break down the line, however the Angular Material team does have something similar in the pipeline.
这篇关于扩展 MatRowDef的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!