Angular 8 - 如何通过属性查询 DOM 元素?
Angular 8 - How to query DOM elements by their attributes?
我有一个动态生成的 HTML 5 table 使用 renderer2:
const td = this.renderer.createElement('td');
this.renderer.setProperty(td, 'id', letter + i);
this.renderer.setAttribute(td, 'contenteditable', 'true');
this.renderer.setAttribute(td, 'r', i + '');
this.renderer.setAttribute(td, 'c', j + '');
table具有以下结构
<table _ngcontent-iji-c1="" appcreatereport="">
<tr _ngcontent-iji-c1="">
<td _ngcontent-iji-c1="">1</td>
<td _ngcontent-iji-c1="" id="A1" contenteditable="true" r="1" c="1"></td>
<td _ngcontent-iji-c1="" id="B1" contenteditable="true" r="1" c="2"></td>
<td _ngcontent-iji-c1="" id="C1" contenteditable="true" r="1" c="3"></td>
<td _ngcontent-iji-c1="" id="D1" contenteditable="true" r="1" c="4"></td>
<td _ngcontent-iji-c1="" id="E1" contenteditable="true" r="1" c="5"></td>
</tr>
...
每个 <td>
都有一个 "id"、一个行号 "r" 和一个列号 "c"
我正在尝试仅使用 angular(所以没有 jquery)并且我查看了许多现有的数据网格,但它们从未完全涵盖我计划做的事情并扩展它们似乎比构建我需要的更复杂。
我有两个问题。
- 我的理解是,我不应该直接在 Angular 中操作 DOM,如果元素没有本地引用,我如何访问它们? (或者当我在 renderer2 中生成
<td
> 元素时如何添加本地引用。<TD>
中的文本将需要更新,例如当我从 excel.
- 如何按属性查询元素,所以我想要 r=1 和 c=4 的元素(而不是按 id "D1" 查询)。我只找到了仅适用于引用的@ViewChild。
我目前通过以下方式设置 TD 元素的文本:
(document.getElementById(
'C1'
) as HTMLTableDataCellElement).innerHTML = '123;
我怎样才能以更 "Angular" 的方式做到这一点?
最好的方法是更改设计以使用 table 元素数组和 *ngFor
。
要将其从页面中删除,您可以使用 *ngIf="elements.length === 0"
;
let elements = [{r:1, c: 1, value:''}, {r:1, c: 2, value:''} ... ];
elements[1].value = '123';
<td *ngFor="let el of elements" [r] = "el.r" [c]="el.c">{{el.value}}<\td>
在这种情况下,您可以直接使用元素数组访问每个 td
值。
作为替代方案 - ng-template
可用于将 table 保留在 html 中,但在需要时才会显示。
有点不清楚你想要什么。但这是 few scenarios:
的镜头
- 选择复选框过滤列表
- 单击一个项目会使用该值更新另一个元素
首先只是一个假人 class:
export class RowData {
Name:string;
Id:number;
Row:number;
Column: number;
Visible: boolean = true;
}
使用虚拟数据:
items: RowData[] = [
{
Name: "One",
Id:1,
Row:1,
Column:1,
Visible:true,
},
{
Name: "Two",
Id:2,
Row:2,
Column:2,
Visible:true,
},
{
Name: "Another Row",
Id:5,
Row:3,
Column:3,
Visible:true,
},
{
Name: "Yep",
Id:4,
Row:4,
Column:4,
Visible:true,
},
]
}
对于视图,我有两种方式绑定几个事件:
<hello name="{{ name }}"></hello>
<p>
Start editing to see some magic happen :)
</p>
<div>
<input type="checkbox" name="Toggle Row" (click)="toggleRows()" /> Toggle Rows <br>
</div>
<div *ngFor="let item of items">
<div (click)="showMe(item)" *ngIf=item.Visible>{{item.Name}}</div>
</div>
<label *ngIf="clicked">{{clicked.Name}}</label>
下面是事件及其相关属性:
toggleRow2Col2: boolean = true;
clicked: RowData;
showMe(elem){
this.clicked = elem;
}
toggleRows(){
this.toggleRow2Col2 = !this.toggleRow2Col2;
if (!this.toggleRow2Col2){
this.items.forEach(function(item){
if (item.Row != 2 && item.Column != 2){
item.Visible = false;
}
})
}
else {
this.items.forEach(function(item) {
item.Visible = true;
})
}
}
想法是,是的,我们可以通过属性和绑定过滤和更改 DOM,而 而不是 通过 JS / JQuery。
我有一个动态生成的 HTML 5 table 使用 renderer2:
const td = this.renderer.createElement('td');
this.renderer.setProperty(td, 'id', letter + i);
this.renderer.setAttribute(td, 'contenteditable', 'true');
this.renderer.setAttribute(td, 'r', i + '');
this.renderer.setAttribute(td, 'c', j + '');
table具有以下结构
<table _ngcontent-iji-c1="" appcreatereport="">
<tr _ngcontent-iji-c1="">
<td _ngcontent-iji-c1="">1</td>
<td _ngcontent-iji-c1="" id="A1" contenteditable="true" r="1" c="1"></td>
<td _ngcontent-iji-c1="" id="B1" contenteditable="true" r="1" c="2"></td>
<td _ngcontent-iji-c1="" id="C1" contenteditable="true" r="1" c="3"></td>
<td _ngcontent-iji-c1="" id="D1" contenteditable="true" r="1" c="4"></td>
<td _ngcontent-iji-c1="" id="E1" contenteditable="true" r="1" c="5"></td>
</tr>
...
每个 <td>
都有一个 "id"、一个行号 "r" 和一个列号 "c"
我正在尝试仅使用 angular(所以没有 jquery)并且我查看了许多现有的数据网格,但它们从未完全涵盖我计划做的事情并扩展它们似乎比构建我需要的更复杂。
我有两个问题。
- 我的理解是,我不应该直接在 Angular 中操作 DOM,如果元素没有本地引用,我如何访问它们? (或者当我在 renderer2 中生成
<td
> 元素时如何添加本地引用。<TD>
中的文本将需要更新,例如当我从 excel. - 如何按属性查询元素,所以我想要 r=1 和 c=4 的元素(而不是按 id "D1" 查询)。我只找到了仅适用于引用的@ViewChild。
我目前通过以下方式设置 TD 元素的文本:
(document.getElementById(
'C1'
) as HTMLTableDataCellElement).innerHTML = '123;
我怎样才能以更 "Angular" 的方式做到这一点?
最好的方法是更改设计以使用 table 元素数组和 *ngFor
。
要将其从页面中删除,您可以使用 *ngIf="elements.length === 0"
;
let elements = [{r:1, c: 1, value:''}, {r:1, c: 2, value:''} ... ];
elements[1].value = '123';
<td *ngFor="let el of elements" [r] = "el.r" [c]="el.c">{{el.value}}<\td>
在这种情况下,您可以直接使用元素数组访问每个 td
值。
作为替代方案 - ng-template
可用于将 table 保留在 html 中,但在需要时才会显示。
有点不清楚你想要什么。但这是 few scenarios:
的镜头- 选择复选框过滤列表
- 单击一个项目会使用该值更新另一个元素
首先只是一个假人 class:
export class RowData {
Name:string;
Id:number;
Row:number;
Column: number;
Visible: boolean = true;
}
使用虚拟数据:
items: RowData[] = [
{
Name: "One",
Id:1,
Row:1,
Column:1,
Visible:true,
},
{
Name: "Two",
Id:2,
Row:2,
Column:2,
Visible:true,
},
{
Name: "Another Row",
Id:5,
Row:3,
Column:3,
Visible:true,
},
{
Name: "Yep",
Id:4,
Row:4,
Column:4,
Visible:true,
},
]
}
对于视图,我有两种方式绑定几个事件:
<hello name="{{ name }}"></hello>
<p>
Start editing to see some magic happen :)
</p>
<div>
<input type="checkbox" name="Toggle Row" (click)="toggleRows()" /> Toggle Rows <br>
</div>
<div *ngFor="let item of items">
<div (click)="showMe(item)" *ngIf=item.Visible>{{item.Name}}</div>
</div>
<label *ngIf="clicked">{{clicked.Name}}</label>
下面是事件及其相关属性:
toggleRow2Col2: boolean = true;
clicked: RowData;
showMe(elem){
this.clicked = elem;
}
toggleRows(){
this.toggleRow2Col2 = !this.toggleRow2Col2;
if (!this.toggleRow2Col2){
this.items.forEach(function(item){
if (item.Row != 2 && item.Column != 2){
item.Visible = false;
}
})
}
else {
this.items.forEach(function(item) {
item.Visible = true;
})
}
}
想法是,是的,我们可以通过属性和绑定过滤和更改 DOM,而 而不是 通过 JS / JQuery。