angular 中可点击的 table 个单元格
Clickable table cells in angular
我有一个 table 有行。当我点击一个单元格时,它的颜色变成了红色,但一次只能有一个是红色的。如果我点击另一个单元格,之前的单元格应该不再是红色的。我不知道如何一次只使一个单元格变红。你有什么想法吗?
html 文件:
<table>
<tr appFocusCell><td > </td></tr>
<tr appFocusCell><td> </td></tr>
<tr appFocusCell><td> </td></tr>
<tr appFocusCell><td> </td></tr>
<tr appFocusCell><td> </td></tr>
<tr appFocusCell><td> </td></tr>
<tr appFocusCell><td></td></tr>
</table>
焦点-cell.directive 文件:
import {Directive, ElementRef, HostListener, Renderer2} from '@angular/core';
@Directive({
selector: '[appFocusCell]'
})
export class FocusCellDirective {
constructor(private e:ElementRef,private render: Renderer2) { }
ngOnInit() {
}
@HostListener('click')
onClick(){
const div = this.e.nativeElement;
this.render.setStyle(div,'background','red')
}
}
您可能想要添加关于当前选择哪一行的逻辑,方法是创建一个父指令来为当前单击的行添加书签。
这个想法是,有了关于当前点击哪一行的信息,这个父指令可以删除点击的旧行的突出显示,并改为突出显示新点击的行。
这是一个示例解决方案。我还没有测试过它,但希望它背后的想法很清楚。
<table appTable> <!-- make new directive-->
<tr appFocusCell>...</tr>
<tr appFocusCell>...</tr>
...
</table>
@Directive({
selector: '[appFocusCell]'
})
export class FocusCellDirective implements OnDestroy {
readonly onClick$ = new Subject<void>(); // emit when host is clicked
@HostListener('click')
onClick() {
this.onClick$.next();
}
// set/unset row background color whether active/inactive
set isActive(isActive: boolean) {
this.e.style.backgroundColor = isActive ? 'red' : 'unset';
}
constructor(private e: ElementRef<HTMLElement>) { }
ngOnDestroy() {
this.onClick$.complete();
}
}
@Directive({
selector: '[appTable]'
})
export class AppTableDirective implements AfterContentInit, OnDestroy {
private clickedRow: FocusCellDirective | null = null; // bookmark currently clicked row
@ContentChildren(FocusCellDirective, { descendants: true })
private rows!: QueryList<FocusCellDirective>; // get all table rows
private onDestroy = new Subject<void>();
ngAfterContentInit() {
// listen to any rows clicked
this.rows.forEach((row) => {
row.onClick$
.pipe(takeUntil(this.onDestroy))
.subscribe(() => this.setClicked(row)); // update currently clicked row
});
}
private setClicked(row: FocusCellDirective) {
if(this.clickedRow !== null) {
this.clickedRow.isActive = false; // remove highlight of previously clicked row
}
row.isActive = true; // highlight currently clicked row
this.clickedRow = row; // bookmark currently clicked row
}
ngOnDestroy() {
this.onDestroy.next();
this.onDestroy.complete();
}
}
以下是代码示例
html
<table border="1">
<tbody>
<tr>
<td appCellClick>
Cell1.1
</td>
<td appCellClick>
Cell1.2
</td>
</tr>
<tr>
<td appCellClick>
Cell2.1
</td>
<td appCellClick>
Cell2.2
</td>
</tr>
</tbody>
</table>
指令
import { Directive, HostListener, Renderer2 } from '@angular/core';
@Directive({
selector: '[appCellClick]',
})
export class CellClickDirective {
@HostListener('click', ['$event']) onClick(ev) {
const curEl = ev.target; //TAKE CLICKED CELL ELEMENT
let parentEl:any = {};
// CHECK THE PARENT TABLE ELEMENT
const parentChecker = (el) => {
if (el.nodeName == 'TABLE') {
parentEl = el;
} else {
parentChecker(el.parentElement);
}
};
parentChecker(curEl);
// PARENT TABLE FOUND - REMOVE EXISTING CSS-CLASS
if(parentEl){
const addedBg = parentEl.querySelectorAll('td.bg-red');
addedBg.forEach((e) => {
e.setAttribute('class', e.getAttribute('class').replace('bg-red',''));
});
}
this.renderer.addClass(curEl, 'bg-red');
}
constructor(
private renderer: Renderer2
) {}
}
css
.bg-red{
background-color: red;
}
我有一个 table 有行。当我点击一个单元格时,它的颜色变成了红色,但一次只能有一个是红色的。如果我点击另一个单元格,之前的单元格应该不再是红色的。我不知道如何一次只使一个单元格变红。你有什么想法吗?
html 文件:
<table>
<tr appFocusCell><td > </td></tr>
<tr appFocusCell><td> </td></tr>
<tr appFocusCell><td> </td></tr>
<tr appFocusCell><td> </td></tr>
<tr appFocusCell><td> </td></tr>
<tr appFocusCell><td> </td></tr>
<tr appFocusCell><td></td></tr>
</table>
焦点-cell.directive 文件:
import {Directive, ElementRef, HostListener, Renderer2} from '@angular/core';
@Directive({
selector: '[appFocusCell]'
})
export class FocusCellDirective {
constructor(private e:ElementRef,private render: Renderer2) { }
ngOnInit() {
}
@HostListener('click')
onClick(){
const div = this.e.nativeElement;
this.render.setStyle(div,'background','red')
}
}
您可能想要添加关于当前选择哪一行的逻辑,方法是创建一个父指令来为当前单击的行添加书签。
这个想法是,有了关于当前点击哪一行的信息,这个父指令可以删除点击的旧行的突出显示,并改为突出显示新点击的行。
这是一个示例解决方案。我还没有测试过它,但希望它背后的想法很清楚。
<table appTable> <!-- make new directive-->
<tr appFocusCell>...</tr>
<tr appFocusCell>...</tr>
...
</table>
@Directive({
selector: '[appFocusCell]'
})
export class FocusCellDirective implements OnDestroy {
readonly onClick$ = new Subject<void>(); // emit when host is clicked
@HostListener('click')
onClick() {
this.onClick$.next();
}
// set/unset row background color whether active/inactive
set isActive(isActive: boolean) {
this.e.style.backgroundColor = isActive ? 'red' : 'unset';
}
constructor(private e: ElementRef<HTMLElement>) { }
ngOnDestroy() {
this.onClick$.complete();
}
}
@Directive({
selector: '[appTable]'
})
export class AppTableDirective implements AfterContentInit, OnDestroy {
private clickedRow: FocusCellDirective | null = null; // bookmark currently clicked row
@ContentChildren(FocusCellDirective, { descendants: true })
private rows!: QueryList<FocusCellDirective>; // get all table rows
private onDestroy = new Subject<void>();
ngAfterContentInit() {
// listen to any rows clicked
this.rows.forEach((row) => {
row.onClick$
.pipe(takeUntil(this.onDestroy))
.subscribe(() => this.setClicked(row)); // update currently clicked row
});
}
private setClicked(row: FocusCellDirective) {
if(this.clickedRow !== null) {
this.clickedRow.isActive = false; // remove highlight of previously clicked row
}
row.isActive = true; // highlight currently clicked row
this.clickedRow = row; // bookmark currently clicked row
}
ngOnDestroy() {
this.onDestroy.next();
this.onDestroy.complete();
}
}
以下是代码示例
html
<table border="1">
<tbody>
<tr>
<td appCellClick>
Cell1.1
</td>
<td appCellClick>
Cell1.2
</td>
</tr>
<tr>
<td appCellClick>
Cell2.1
</td>
<td appCellClick>
Cell2.2
</td>
</tr>
</tbody>
</table>
指令
import { Directive, HostListener, Renderer2 } from '@angular/core';
@Directive({
selector: '[appCellClick]',
})
export class CellClickDirective {
@HostListener('click', ['$event']) onClick(ev) {
const curEl = ev.target; //TAKE CLICKED CELL ELEMENT
let parentEl:any = {};
// CHECK THE PARENT TABLE ELEMENT
const parentChecker = (el) => {
if (el.nodeName == 'TABLE') {
parentEl = el;
} else {
parentChecker(el.parentElement);
}
};
parentChecker(curEl);
// PARENT TABLE FOUND - REMOVE EXISTING CSS-CLASS
if(parentEl){
const addedBg = parentEl.querySelectorAll('td.bg-red');
addedBg.forEach((e) => {
e.setAttribute('class', e.getAttribute('class').replace('bg-red',''));
});
}
this.renderer.addClass(curEl, 'bg-red');
}
constructor(
private renderer: Renderer2
) {}
}
css
.bg-red{
background-color: red;
}