扩展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
扩展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);
}
}
然后我简单地用*expandableRowDef="..."
切换了*matRowDef="..."
,它可以很好地编译并且在运行时不会失败.
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
创建自定义组件来工作的a>,然后使用 @ViewChildren
以获得列表表行,然后单击所选表行,将自定义组件插入指定的index
处,并使用
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屋!