提问人:MyNameIsJeff 提问时间:9/12/2023 更新时间:9/12/2023 访问量:69
在 Angular HTTP 请求动态填充表行中的子表后,在当前页面中找不到节点
Node cannot be found in the current page after Angular HTTP request for dynamically filling a subtable within a table row
问:
我的项目旨在加载一个包含每个进程的进程和子进程的表。为了实现这一点,对于可扩展的子进程行,我想到了以下几点:偶数索引行是进程,奇数索引行是包含另一个表的表行,上面进程的子进程对应于它们。
问题是我实现了一个弹出窗口,当单击子进程子表的子进程行上的复选框时,该弹出窗口应该会打开。
通过本地数据,它可以完美地工作,但是通过HTTP,当我在开发工具中使用“检查”命令选择它时,它会说“在当前页面中找不到节点”。此外,它知道我有 HTML,但即使在检查了首先加载进程之后,我也无法使用它,然后加载了该进程的子进程(我确保在隐藏行的第一次扩展时只加载一次),使用 sessionStorage 轻松检索它们无论是 DOM 还是组件。
toggledIndex 变量是通过 router-outlet 从另一个组件接收的要打开的索引。ng-container *ngIf 对此索引的检查用于检查是否对该行进行了特定的 HTTP 调用,toggledIndex 是组件初始化时的第一个,因此是一种特殊情况。
进程菜单.组件.html:
<div id="content">
<ng-container *ngIf="processesLoaded | async">
<table>
<ng-container *ngFor="let process of processes; let i=index">
<tr style="cursor: pointer">
<td class="processName" (click)="toggleExpanded($event,i)">
<i [ngClass]="i===toggledIndex ? 'fa fa-chevron-down' : 'fa fa-chevron-right'"></i>
<p>{{process.name}}</p>
</td>
<td class="processCheckbox">
<div> </div>
</td>
<td
[ngClass]="i===toggledIndex ? 'procHead black' : 'procHead white'"
(click)="toggleExpanded($event,i)">
Description of the requirement
</td>
<td
[ngClass]="i===toggledIndex ? 'procHead black' : 'procHead white'"
(click)="toggleExpanded($event,i)">
Overall intent of the requirement
</td>
</tr>
<ng-container *ngIf="i===toggledIndex">
<tr style="width: 100%; height: fit-content;">
<td colspan="4" style="height: fit-content; padding: 0 20px 0 20px;">
<table class="subprocessesTable">
<ng-container *ngIf="get(i)">
<ng-container *ngFor="let subprocess of get(i).subprocesses; let j=index">
<tr class="subprocessRow">
<td class="subprocessName">{{subprocess.name}}</td>
<td class="subprocessState">
<div
style="pointer-events: auto; cursor: pointer;"
(click)="toggleLevelPopup($event)">
</div>
</td>
<td class="pop-up">
<!-- <level-pop-up style="display: none;"></level-pop-up> -->
<level-pop-up></level-pop-up>
</td>
<td class="descReq">
<ng-container *ngIf="subprocess.descriptionReq.length>160">
<div
style="cursor: pointer"
onclick="if(this.nextSibling.style.visibility==='hidden') this.nextSibling.style.visibility=''">
{{trim(subprocess.descriptionReq)}}
</div>
<text-pop-up style="visibility: hidden;" [popText]="subprocess.descriptionReq"></text-pop-up>
</ng-container>
<ng-container *ngIf="subprocess.descriptionReq.length<=160">
{{subprocess.descriptionReq}}
</ng-container>
</td>
<td class="intentReq">
<ng-container *ngIf="subprocess.intentReq.length>160">
<div
style="pointer-events: auto; cursor: pointer"
onclick="if(this.nextSibling.style.visibility==='hidden') this.nextSibling.style.visibility=''">
{{trim(subprocess.intentReq)}}
</div>
<text-pop-up style="visibility: hidden;" [popText]="subprocess.intentReq"></text-pop-up>
</ng-container>
<ng-container *ngIf="subprocess.intentReq.length<=160">
{{subprocess.intentReq}}
</ng-container>
</td>
</tr>
</ng-container>
</ng-container>
</table>
</td>
</tr>
</ng-container>
<ng-container *ngIf="i!==toggledIndex">
<tr style="display: none; height: 0; width: 100%">
<td colspan="4" style="height: fit-content; padding: 0 20px 0 20px;">
<table class="subprocessesTable">
<ng-container *ngIf="get(i)">
<ng-container *ngFor="let subprocess of get(i).subprocesses; let j=index">
<tr class="subprocessRow">
<td class="subprocessName">{{subprocess.name}}</td>
<td class="subprocessState">
<div
style="cursor: pointer;"
(click)="toggleLevelPopup($event)">
</div>
</td>
<td class="pop-up">
<!-- <level-pop-up style="display: none;"></level-pop-up> -->
<level-pop-up></level-pop-up>
</td>
<td class="descReq">
<ng-container *ngIf="subprocess.descriptionReq.length>160">
<div
style="cursor: pointer"
onclick="if(this.nextSibling.style.visibility==='hidden') this.nextSibling.style.visibility=''">
{{trim(subprocess.descriptionReq)}}
</div>
<text-pop-up style="visibility: hidden;" [popText]="subprocess.descriptionReq"></text-pop-up>
</ng-container>
<ng-container *ngIf="subprocess.descriptionReq.length<=160">
{{subprocess.descriptionReq}}
</ng-container>
</td>
<td class="intentReq">
<ng-container *ngIf="subprocess.intentReq.length>160">
<div
style="cursor: pointer"
onclick="if(this.nextSibling.style.visibility==='hidden') this.nextSibling.style.visibility=''">
{{trim(subprocess.intentReq)}}
</div>
<text-pop-up style="visibility: hidden;" [popText]="subprocess.intentReq"></text-pop-up>
</ng-container>
<ng-container *ngIf="subprocess.intentReq.length<=160">
{{subprocess.intentReq}}
</ng-container>
</td>
</tr>
</ng-container>
</ng-container>
</table>
</td>
</tr>
</ng-container>
</ng-container>
</table>
</ng-container>
</div>
进程-menu.component.ts:
httpSubscription1: any;
httpSubscription2: any;
httpSubscription3: any;
processes: any = [];
subprocessesOfProcess: any = [];
toggledIndex: any;
processesLoaded: Promise<boolean>;
constructor(
private globalData: DataBetweenUnrelatedService,
private httpService: HttpRetrieveService,
private router: Router,
private activatedRoute: ActivatedRoute){}
ngOnInit(){
this.activatedRoute.queryParams.subscribe (params => this.toggledIndex = parseInt(params["toggledIndex"]));
console.log('INIT MENU', this.toggledIndex);
this.httpSubscription1 = this.httpService.getData(myGlobals.URL+'/processes/allProcesses').subscribe(data => {
this.processes = data;
this.globalData.processExpansionState = [];
this.globalData.subprocessesCalled = [];
this.subprocessesOfProcess = [];
for(let i=0; i<this.processes.length; i++){
this.globalData.processExpansionState.push(i===this.toggledIndex ? true : false);
this.globalData.subprocessesCalled.push(i===this.toggledIndex ? true : false);
this.subprocessesOfProcess.push({});
}
this.processesLoaded = Promise.resolve(true);
});
this.httpSubscription2 = this.httpService.getData(myGlobals.URL+`/subprocesses/allSubprocessesOfAProcess?processId=${this.toggledIndex+1}`).subscribe( data => {
this.subprocessesOfProcess[this.toggledIndex] = {
processIndex: this.toggledIndex,
subprocesses: data
};
this.save(this.toggledIndex, JSON.stringify(this.subprocessesOfProcess[this.toggledIndex]));
});
}
ngOnDestroy(){
if(this.httpSubscription1) this.httpSubscription1.unsubscribe();
if(this.httpSubscription2) this.httpSubscription2.unsubscribe();
if(this.httpSubscription3) this.httpSubscription3.unsubscribe();
console.log('DESTROY MENU');
}
save(key, value){
sessionStorage.setItem(key, value);
}
get(key){
return JSON.parse(sessionStorage.getItem(key));
}
switchToOverview(event){
this.router.navigate(['/','dashboard']);
}
trim(string){
return string.slice(0, 160)+'...';
}
toggleLevelPopup(event){
console.log(event.target.parentElement.parentElement.firstChild);
// HERE IS WHERE I NEED TO SHOW OR HIDE MY CUSTOM POP-UP COMPONENT WHEN I CLICK
// ON THE ROW CHECKBOX
// BUT THE PROBLEM IS THAT I CAN'T MAKE USE OF THE DYMANICALLY ADDED HTML, WHICH
// ALSO IMPACTS THE POINTER EVENTS THAT I HAD MADE WITHIN THE POP-UP COMPONENT
// (RENDERS IT USELESS BASICALLY)
}
toggleExpanded(event, i){
let clickedRow: any;
let expandedRow: any;
let icon: any;
let description1: any;
let description2: any;
if(i===this.toggledIndex){
clickedRow = event.target.parentElement;
expandedRow = event.target.parentElement.nextSibling;
this.globalData.subprocessesCalled[i]=true;
}else{
clickedRow = event.target.parentElement;
expandedRow = event.target.parentElement.nextSibling.nextSibling;
}
this.globalData.processExpansionState[i] = !this.globalData.processExpansionState[i];
switch(this.globalData.processExpansionState[i]){
case true:
if(!this.globalData.subprocessesCalled[i]){
this.httpSubscription3 = this.httpService.getData(myGlobals.URL+`/subprocesses/allSubprocessesOfAProcess?processId=${i+1}`).subscribe( data => {
this.subprocessesOfProcess[i] = {
processIndex: i,
subprocesses: data
};
this.globalData.subprocessesCalled[i] = !this.globalData.subprocessesCalled[i];
this.save(i, JSON.stringify(this.subprocessesOfProcess[i]));
});
}
icon = clickedRow.children[0].children[0];
icon.classList.remove('fa-chevron-right');
icon.classList.add('fa-chevron-down');
description1 = clickedRow.children[2];
description2 = clickedRow.children[3];
description1.classList.add('black');
description1.classList.remove('white');
description2.classList.add('black');
description2.classList.remove('white');
expandedRow.style.display = '';
expandedRow.style.height = 'fit-content';
break;
case false:
icon = clickedRow.children[0].children[0];
icon.classList.remove('fa-chevron-down');
icon.classList.add('fa-chevron-right');
description1 = clickedRow.children[2];
description2 = clickedRow.children[3];
description1.classList.add('white');
description1.classList.remove('black');
description2.classList.add('white');
description2.classList.remove('black');
expandedRow.style.display = 'none';
expandedRow.style.height = '0';
break;
}
}
答: 暂无答案
评论