В настоящее время я разрабатываю веб-приложение, которое позволяет пользователям изменять параметры своего центра затрат как Администратор.
Недавно я прошел онлайн-урок Angular и вскоре понял, что я реализовал все в одном компоненте (который не является угловым).
Итак, я разделил свое приложение на несколько компонентов:
- APP
- Заголовок
- Сообщения
- CostcenterTable
- CostcenterRow
У меня есть 2 разные службы, которые загружают данные с помощью RESTCalls.
У таблицы CostcenterTable есть ngFor (по сравнению с центрами затрат из Service), и она генерирует различные позиции.
Каждая строка имеет 6 полей, они являются полями ввода, из которых 4 активны.4 поля ввода настроены с помощью NGBTypeahead.
Проблема в том, что, если я загружаю около 30 центров затрат (30 строк), каждый раз, когда я щелкаю где-нибудь GUI (событие клика), вся таблица имеет ОДНУ задержку.
Я пытался понять, почему .. Например, если я использую ngFor с TrackBy, метод TrackBy вызывается несколько раз после каждого события, для каждой строки / поля ввода.Я предполагаю, что это может быть проблемой отставания здесь.
Не должен ли TrackBy помешать ngFor для воссоздания всего после каждого события Zone?
Я также пытался реализовать различные методы ChangeDetectionStategy, например так (и другие ..): - APP (отсоединено) - CostcenterTable (onPush) --- CostcenterRow (onPush)
НоЯ все еще не могу помешать ngFor проверять все после каждого события.
Если я использую обычные поля ввода (без [NgbTypeahead]), лаг значительно уменьшается по всей таблице, но это не решает мою проблему.
Я не очень хорошо понимаю, как это должно быть структурировано, чтобы не отставать.
Вот код:
[APPComponentHtml]:
<app-header [message]="message" [status]="status"></app-header>
<div class="pvContainer">
<app-messages [message]="message"></app-messages>
</div>
<div class="pvContainer" *ngIf="costcenter">
<app-costcentertable [costcenter]="costcenter" [rows]="rows" [captions]="captions"></app-costcentertable>
</div>
[CostcenterTableHtml]:
<div>
<h1>Costcenter Administration</h1>
</div>
<table class="accTable accTableBg table table-bordered tableCostcenter">
<thead class="tableHeadHide">
<tr>
<ng-container *ngFor="let caption of captions">
<th id="colRowNr" *ngIf="caption.row =='#'">{{caption.caption}}</th>
<th id="colNr" *ngIf="caption.row =='NR'">{{caption.caption}}</th>
<th id="colDesc" *ngIf="caption.row =='DESCRIPTION'">{{caption.caption}}</th>
<th id="colRank" *ngIf="caption.row =='RANK1'">{{caption.caption}}</th>
<th id="colRank" *ngIf="caption.row =='RANK2'">{{caption.caption}}</th>
<th id="colRank" *ngIf="caption.row =='RANK3'">{{caption.caption}}</th>
<th id="colRank" *ngIf="caption.row =='RANK4'">{{caption.caption}}</th>
</ng-container>
</tr>
</thead>
<tbody>
<tr *ngFor="let pos of costcenter; let i = index;"
[hidden]="pos.deleted" app-costcenter-row [pos]="pos"
[caption]="captions" [index]="i">
</tr>
</tbody>
</table>
<button class="btn btn-info" (click)="invoice.saveCostCenter()">Save</button>
[CostcenterTableComponent]:
@Component({
selector: 'app-costcentertable',
templateUrl: './costcentertable.component.html',
styleUrls: ['./costcentertable.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CostcentertableComponent implements OnInit {
@Input() costcenter: CostCenterWrapper;
invoice: AllocationComponent;
@Input() rows: string[];
@Input() captions;
constructor(invoice: AllocationComponent, private cd: ChangeDetectorRef) {
this.invoice = invoice;
}
ngOnInit() {
//this.cd.detach();
}
ngAfterViewInit() {
//this.cd.detach();
}
trackRow(index: any, item: any) {
console.log("TrackbyRow started. Returning: " + item);
return item;
}
saveCostCenter() {
this.invoice.saveCostCenter();
}
}
[CostcenterRowHtml]:
<td class="rowNr"><label for="tddescription" id="tddescription">#</label>
<p>{{ index + 1 }}</p></td>
<td><label for="tddescription" id="tddescription">Nr</label><input
type="text" [(ngModel)]="pos.number" [disabled]="true"></td>
<td><label for="tddescription" id="tddescription">Description</label><input
type="text" [(ngModel)]="pos.name" [disabled]="true"></td>
<td><label for="tddescription" id="tddescription">Rank 1</label>
[ngbTypeahead]="invoice.taCC" [resultFormatter]="invoice.formatterRes"
[inputFormatter]="invoice.formatter" <input type="text"
style="text-align: left;" [(ngModel)]="pos.responsible1.ntName"
[required]="true"
(ngModelChange)="invoice.formatSelection(1, 'RESP1', $event)"
(selectItem)="invoice.formatSelection(1, 'RESP1', $event)">
<div class="pvHint">{{pos.responsible1.name}}</div></td>
<td><label for="tddescription" id="tddescription">Rank 2</label> <input
[ngbTypeahead]="invoice.taCC" [resultFormatter]="invoice.formatterRes"
[inputFormatter]="invoice.formatter" type="text"
style="text-align: left;" [(ngModel)]="pos.responsible2.ntName"
(ngModelChange)="invoice.formatSelection(1, 'CC', $event)"
(selectItem)="invoice.formatSelection(1, 'CC', $event)">
<div class="pvHint">{{pos.responsible2.name}}</div></td>
<td><label for="tddescription" id="tddescription">Rank 3</label> <input
[ngbTypeahead]="invoice.taCC" [resultFormatter]="invoice.formatterRes"
[inputFormatter]="invoice.formatter" type="text"
style="text-align: left;" [(ngModel)]="pos.responsible3.ntName"
(ngModelChange)="invoice.formatSelection(1, 'CC', $event)"
(selectItem)="invoice.formatSelection(1, 'CC', $event)">
<div class="pvHint">{{pos.responsible3.name}}</div></td>
<td><label for="tddescription" id="tddescription">Rank 4</label> <input
[ngbTypeahead]="invoice.taCC" [resultFormatter]="invoice.formatterRes"
[inputFormatter]="invoice.formatter" type="text"
style="text-align: left;" [(ngModel)]="pos.responsible4.ntName"
[required]="true"
(ngModelChange)="invoice.formatSelection(1, 'CC', $event)"
(selectItem)="invoice.formatSelection(1, 'CC', $event)">
<div class="pvHint">{{pos.responsible4.name}}</div></td>
[CostcenterRowComponent]:
@Component({
selector: '[app-costcenter-row]',
templateUrl: './costcenter-row.component.html',
styleUrls: ['./costcenter-row.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CostcenterRowComponent implements OnInit {
@Input() index: number;
@Input() caption;
@Input() pos;
invoice: AllocationComponent;
constructor(invoice: AllocationComponent) {
this.invoice = invoice;
}
ngOnInit() {
}
}