我创建了一个 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
我在 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