如何为Alfresco ADF的Angular Material Table中所有mat-row添加draggable属性?
draggable="true" to Alfresco ADF Datatable's mat-row Elements Great question! Since Alfresco ADF's datatable is built on top of Angular Material Table, there are a few more Angular-idiomatic ways to add the draggable="true" attribute to each mat-row—avoiding direct DOM manipulation where possible (though Renderer2/ElementRef work, these approaches align better with framework best practices):
1. Custom Row Template (Most Recommended)
Alfresco ADF's adf-datatable supports custom row templates via the adf-datatable-row-template directive. This lets you directly add the draggable attribute to the mat-row in your template, no DOM hacking required.
Here's a quick example:
<adf-datatable [data]="documentList" [columns]="tableColumns"> <ng-template let-row="row" let-node="node" adf-datatable-row-template> <!-- Add draggable directly to mat-row, plus any data attributes you need for drag logic --> <mat-row draggable="true" [attr.data-node-id]="node.id" (dragstart)="handleDragStart($event, node)"> <!-- Reuse default cell rendering or customize as needed --> <mat-cell *ngFor="let column of tableColumns"> {{ row[column.key] }} </mat-cell> </mat-row> </ng-template> </adf-datatable>
This approach is clean, declarative, and fits perfectly with Angular and ADF's design patterns. You can also bind drag-related events (like dragstart or dragend) directly to your component methods here.
2. Custom Directive for Reusability
If you need this drag behavior across multiple datatables, create an Angular directive that automatically adds the draggable attribute to any mat-row it's applied to.
First, create the directive:
import { Directive, ElementRef, OnInit } from '@angular/core'; @Directive({ selector: 'mat-row[adf-draggable-row]' // Targets mat-row elements with this attribute }) export class DraggableMatRowDirective implements OnInit { constructor(private elRef: ElementRef) {} ngOnInit(): void { // Add the draggable attribute this.elRef.nativeElement.setAttribute('draggable', 'true'); // Optional: Bind drag event handlers directly in the directive this.elRef.nativeElement.addEventListener('dragstart', (event: DragEvent) => { const nodeId = this.elRef.nativeElement.dataset.nodeId; event.dataTransfer?.setData('text/plain', nodeId); }); } }
Then use it in your datatable template:
<adf-datatable [data]="documentList" [columns]="tableColumns"> <ng-template let-row="row" let-node="node" adf-datatable-row-template> <mat-row adf-draggable-row [attr.data-node-id]="node.id"> <!-- Cell content here --> </mat-row> </ng-template> </adf-datatable>
Don't forget to declare the directive in your Angular module! This keeps your code DRY and makes it easy to enable drag functionality anywhere.
3. Attribute Binding (Simpler One-off Use)
For a quick one-off implementation, you can directly bind the draggable attribute using Angular's property binding syntax.
In your component class, you can even conditionally enable it if needed:
// Component class isRowDraggable(): boolean { return true; // Or add logic to toggle based on row data }
Then in the template:
<adf-datatable [data]="documentList" [columns]="tableColumns"> <ng-template let-row="row" adf-datatable-row-template> <mat-row [draggable]="isRowDraggable()"> <!-- Cell content here --> </mat-row> </ng-template> </adf-datatable>
Angular will automatically convert the boolean value to the correct draggable attribute value ("true" or "false") in the DOM.
To recap, the custom row template (method 1) is the best starting point—it's straightforward and aligns with how ADF and Angular Material are designed to be used. If you need to reuse this behavior across components, the directive (method 2) is the way to go.
内容的提问来源于stack exchange,提问作者user5417542

