我创建了一个 angular 指令来设置 table 的样式。但是 table 在点击分页时会丢失指令中定义的样式

I have created an angular directive for styling a table. But table loses the styles defined in the directive when pagination is clicked

我在 Angular 中创建了以下自定义指令:

@Directive({
    selector: '[tableTheme]'
})
export class TableThemeDirective implements OnInit, AfterViewInit {
    tableElement: HTMLTableElement;

    constructor(private el: ElementRef, private renderer: Renderer2) {}

    ngOnInit(): void {
        this.tableElement = this.el.nativeElement;

        this.renderer.setStyle(this.tableElement, 'width', '100%');
        this.renderer.setStyle(this.tableElement, 'border-collapse', 'separate');
        this.renderer.setStyle(this.tableElement, 'border-spacing', '0 1em');
        this.renderer.setStyle(this.tableElement, 'color', 'white');

        const thElements: NodeListOf<HTMLTableCellElement> = this.tableElement.querySelectorAll('th');

        thElements.forEach((el) => {
            this.renderer.setStyle(el, 'height', '2em');
            this.renderer.setStyle(el, 'margin-bottom', '1em');
            this.renderer.setStyle(el, 'padding', '1em');
        });        
    }

    ngAfterViewInit(): void {
        const tdElements: NodeListOf<HTMLTableCellElement> = this.tableElement.querySelectorAll('td');

        tdElements.forEach((el) => {
            this.renderer.setStyle(el, 'background-color', 'var(--primary-clr-light)');            
        });

        let tdFirstChildElements: HTMLTableCellElement[] = [];
        let tdLastChildElements: HTMLTableCellElement[] = [];

        tdElements.forEach((el) => {
            const parentNode: ParentNode = el.parentNode;
            
            if(el === parentNode.firstElementChild) {
                tdFirstChildElements.push(el);
            } else if(el === parentNode.lastElementChild) {
                tdLastChildElements.push(el);
            }
        });

        console.log(tdFirstChildElements);
        console.log(tdLastChildElements);
        

        tdFirstChildElements.forEach((el) => {
            this.renderer.setStyle(el, 'border-left-style', 'solid');
            this.renderer.setStyle(el, 'border-top-left-radius', '10px');
            this.renderer.setStyle(el, 'border-bottom-left-radius', '10px');
            this.renderer.setStyle(el, 'padding', '1em');
        });

        tdLastChildElements.forEach((el) => {
            this.renderer.setStyle(el, 'border-right-style', 'solid');
            this.renderer.setStyle(el, 'border-top-right-radius', '10px');
            this.renderer.setStyle(el, 'border-bottom-right-radius', '10px');
            this.renderer.setStyle(el, 'padding', '1em');
        });
    }
}

然后我使用这个指令来设置样式 table:

<table class="user-table" tableTheme>
    <thead>
        <tr>
            <th>ID</th> 
            <th>Name</th>
            <th>Username</th>
            <th>Role</th>
            <th>Email</th>
            <th>Contact Number</th>
            <th>Action</th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let user of displayingUsers">
            <td>{{ user.id }}</td>
            <td>{{ user.name }}</td>
            <td>{{ user.username }}</td>
            <td>{{ user.role }}</td>
            <td>{{ user.email }}</td>
            <td>{{ user.contactNumber }}</td>
            <td>Action</td>
        </tr>
    </tbody>
  </table>

如您所见,该指令已附加到 table 元素。

然后我在 table:

下面添加一些分页逻辑
  <div class="paginator">
    <button 
        class="btn btn-primary" 
        type="button" 
        *ngFor="let item of createRange(collectionLength); let i = index"
        (click)="onPaginationButtonClick(i + 1)">
        {{ i + 1 }}
    </button>
  </div>

分页的实现:

export class UsersComponent implements OnInit {

  users: User[];
  displayingUsers: User[];
  currentPage: number = 1;
  perPage = 4;
  collectionLength: number;

  createRange(count: number): number[] {
    return new Array(count);
  }

  onPaginationButtonClick(clickedPage: number): void {
    this.displayingUsers = this.users.slice((clickedPage - 1) * this.perPage, (clickedPage - 1) * this.perPage + this.perPage);
  }

  constructor() { }

  ngOnInit(): void {
    this.users = USERS;
    this.onPaginationButtonClick(1);
    this.collectionLength = Math.ceil(this.users.length / this.perPage)
  }
}

分页完全有效。但是一旦分页按钮被点击,table 就会失去指令中定义的样式。 (以下屏幕截图显示了问题。)

在点击分页按钮之前

点击分页按钮后

如您所见,table 丢失了指令中定义的样式。

如何保持指令中定义的样式?

您可以使用renderer.addClass为元素添加样式

ngOnInit(): void {
    this.tableElement = this.el.nativeElement;
    // add class(table-theme) to the component.css
    this.renderer.addClass(this.el.nativeElement, 'table-theme');
  }

在 HTML 中,将 table 包裹在 div 中并将您的指令应用于 div

<div table-theme>
 <table>......</table>
<div>

Please find the working solution link below
https://stackblitz.com/edit/angular-ivy-9fqtkq?file=src%2Fapp%2Fapp.component.ts