[英]Angular child component Table
我有 2 個組件,即組件 A 和 B,在組件 AI 中稱為子組件,即組件 B,它是應用程序團隊管理選擇器(子組件)的表。
如果我將選項卡切換到 Teams,它應該呈現子組件,即 app-team-management。 現在它能夠呈現子組件的前端但無法呈現子組件數據,調用了 app-team-management 但它沒有呈現數據。 app-team-management 的 ngOnInit 也沒有渲染或調用
我還向子組件的 ngOnInit 添加了一個控制台日志,這是 app-team-management 但 ngOnInit 沒有初始化
代碼似乎有什么問題? 為什么當我調用子組件 app-team-management 時它沒有呈現數據甚至調用 ngOnInit? . 感謝您的幫助和建議。 贊賞。
#組件A HTML
<div headerTabs class="v-bg-color-3">
<mat-tab-group
animationDuration="0ms"
#tabGroup
(selectedTabChange)="tabChanged($event)"
>
<mat-tab label="Users">
<div class="mat-tab-shadow-container">
<div class="mat-tab-shadow"></div>
<div class="tab-content">
</mat-tab>
<mat-tab label="Teams">
<div class="mat-tab-shadow-container">
<div class="mat-tab-shadow"></div>
<div class="tab-content">
<app-team-management [resetFormSubject]="resetFormSubject"></app-team-management>
</div>
</div>
</mat-tab>
</mat-tab-group>
</div>
</app-page-header>
</div>
#Component A switch tab ts代碼
tabChanged(tabChangeEvent: MatTabChangeEvent): void {
this.currentTab = tabChangeEvent.index;
if(this.currentTab !== 1) {
this.pageHeaderTitleData.title.primary = "Users"
this._pageEventMyList();
}
this.pageHeaderTitleData.title.primary = "Teams"
}
#Component B子組件app-team-management代碼
@Component({
selector: 'app-team-management',
templateUrl: './team-management.component.html',
styleUrls: ['./team-management.component.css'],
encapsulation: ViewEncapsulation.None,
animations: velocityAnimations
})
export class TeamManagementComponent implements OnInit {
teamTable: TableData<TeamMembersDropdownDto>;
@Input() resetFormSubject: Subject<boolean> = new Subject<boolean>();
stateModel = new StateModel();
filterFormControl: any;
@ViewChild(MatMultiSort, { static: true }) sort: MatMultiSort;
@ViewChild('searchInput') searchInput: ElementRef;
CLIENT_SIDE = false;accountId: any;
isLoading: boolean;
totalData: number;
currentDisplayedData: any;
constructor(private _notificationService: NotificationService,private _teamService: TeamService,private router: Router,) {
this.teamTable = new TableData<TeamMembersDropdownDto>(
[
{ id: 'name', name: 'name' },
{ id: 'description', name: 'description' },
{ id: 'members', name: 'members' },
{ id: 'transactions', name: 'transactions' },
], { defaultSortParams: ['name'], defaultSortDirs: ['asc'] }
);
this.teamTable.pageSize = 10;
this.teamTable.pageIndex = 0;
this.filterFormControl = new FormGroup({
filters: new FormControl('1')
});
}
ngOnInit(): void {
console.log("render here")
this.resetFormSubject.subscribe(response => {
if(response){
console.log("fdgdfgfd")
}
})
const currentAccountDetails = localStorage.getItem('currAcct') as any;
if (currentAccountDetails) {
this.accountId = JSON.parse(currentAccountDetails).accountId;
}
this.teamTable.dataSource = new MatMultiSortTableDataSource(this.sort, this.CLIENT_SIDE);
this.teamTable.nextObservable.subscribe(() => { this._tableEvent(); });
this.teamTable.sortObservable.subscribe(() => { this._tableEvent(); });
this.teamTable.previousObservable.subscribe(() => { this._tableEvent(); });
this.teamTable.sizeObservable.subscribe(() => { this._tableEvent(); });
// this._getPageCount();
}
private _tableEvent() {
console.log("test")
this.isLoading = true;
this.teamTable.data = [];
this._teamService.getTeamProfileTableDropdown(
this.accountId,
this.teamTable.pageIndex + 1,
this.teamTable.pageSize,
this.searchInput.nativeElement.value,
this.teamTable.sortParams,
this.teamTable.sortDirs
)
.pipe(
finalize(() => this.isLoading = false)
)
.subscribe({
error: err => this._notificationService.showError(err),
next: res => {
this.teamTable.totalElements = res.totalItemCount;
this.totalData = res.totalItemCount;
this.currentDisplayedData = res.lastItemOnPage;
this.teamTable.data = res.items as TeamMembersDropdownDto[];
console.log("res.items" , res.items)
},
complete: noop
});
}
viewTeamsDetails(id: number) {
this.router.navigate(['settings/user/editteam'],
{
queryParams: { id: id }
});
}
}
#子組件 HTML 代碼
<div style="padding-bottom: 22vh;">
<div fxLayout="column" style="padding: 32px;">
<div fxLayout="row" fxLayoutGap="16px">
<div style="padding-right: 16px;">
<span class="table-info"
>Showing {{currentDisplayedData}} of {{totalData}} of
Teams</span
>
</div>
<div [formGroup]="filterFormControl">
<mat-radio-group
aria-label="Select an option"
formControlName="filters"
>
<mat-radio-button value="1" style="padding-right: 32px;"
>Active
</mat-radio-button>
<mat-radio-button *ifRoles="[]" value="2"
>Archived teams (3)</mat-radio-button
>
</mat-radio-group>
</div>
</div>
<mat-card fxLayout="column" class="users-table-list">
<div fxLayout="column" class="users-list">
<div fxLayout="column">
<div fxLayout="column">
<div
class="table"
[ngStyle.gt-md]="{'overflow': 'auto'}"
>
<div fxLayoutAlign="start center">
<mat-form-field
appearance="standard"
class="users-list-filter"
>
<mat-label style="font-size:12px"
>Search in Teams
</mat-label>
<input matInput #searchInput placeholder="" />
</mat-form-field>
</div>
<mat-table
[dataSource]="teamTable.dataSource"
[@animateStagger]="{value:'50'}"
matMultiSort
(matSortChange)="teamTable.onSortEvent()"
>
<ng-container matColumnDef="name">
<mat-header-cell
*matHeaderCellDef
fxHide
fxShow.gt-xs
fxShow.gt-md
mat-multi-sort-header="name"
class="users-table-header"
>
Team Name
</mat-header-cell>
<mat-cell
*matCellDef="let item"
fxHide
fxShow.gt-xs
fxShow.gt-md
>
{{item.name}}
</mat-cell>
</ng-container>
<ng-container matColumnDef="description">
<mat-header-cell
*matHeaderCellDef
fxHide
fxShow.gt-xs
fxShow.gt-md
mat-multi-sort-header="description"
class="users-table-header"
>
Team Description
</mat-header-cell>
<mat-cell
*matCellDef="let item"
fxHide
fxShow.gt-xs
fxShow.gt-md
>
{{item.description || 'None'}}
</mat-cell>
</ng-container>
<ng-container matColumnDef="members">
<mat-header-cell
*matHeaderCellDef
fxHide
fxShow.gt-xs
fxShow.gt-md
mat-multi-sort-header="members"
class="users-table-header"
>
Members
</mat-header-cell>
<mat-cell
*matCellDef="let item"
fxHide
fxShow.gt-xs
fxShow.gt-md
>
<div
*ngFor="let member of item.teamMembersDto;let isLast=last"
>
{{member.firstName}}{{isLast ? '' : ','}}
</div>
</mat-cell>
</ng-container>
<ng-container matColumnDef="transactions">
<mat-header-cell
*matHeaderCellDef
fxHide
fxShow.gt-xs
fxShow.gt-md
mat-multi-sort-header="transactions"
class="users-table-header"
>
Transactions
</mat-header-cell>
<mat-cell
*matCellDef="let item"
fxHide
fxShow.gt-xs
fxShow.gt-md
>
<div>
in
{{ item.teamTransactionDetailsDto.length}}
transactions
</div>
</mat-cell>
</ng-container>
<mat-header-row
*matHeaderRowDef="teamTable.displayedColumns; sticky:true"
style="padding-bottom: 16px;"
>
</mat-header-row>
<mat-row
(click)="viewTeamsDetails(item.id)"
*matRowDef="let item; columns: teamTable.displayedColumns;"
[ngClass]="{'active': stateModel.id === item.id}"
>
</mat-row>
</mat-table>
<mat-progress-bar
*ngIf="isLoading"
mode="indeterminate"
></mat-progress-bar>
<div
class="no-record"
*ngIf="!isLoading && teamTable.totalElements == 0"
>
No Teams
</div>
<mat-paginator
fxLayoutAlign="end start"
[pageSize]="teamTable.pageSize"
[pageIndex]="teamTable.pageIndex"
[pageSizeOptions]="teamTable.pageSizeOptions"
[length]="teamTable.totalElements ? teamTable.totalElements : 0"
(page)="teamTable.onPaginationEvent($event)"
[disabled]="CLIENT_SIDE"
showFirstLastButtons
>
</mat-paginator>
</div>
</div>
</div>
</div>
</mat-card>
</div>
</div>
Mat 選項卡通常會預加載所有組件,這意味着您的 ngOnInit 應該在您單擊第二個選項卡之前被觸發。 這可能意味着它正在嘗試獲取尚不存在的數據。 我會首先嘗試通過添加 ng-template 來延遲加載您的子組件,這應該會在您單擊選項卡時修復 onInit 運行。
<mat-tab label="Teams">
<div class="mat-tab-shadow-container">
<div class="mat-tab-shadow"></div>
<div class="tab-content">
<ng-template>
<app-team-management [resetFormSubject]="resetFormSubject"></app-team-management>
</ng-template>
</div>
</div>
</mat-tab>
其次,我會把這段代碼
this.teamTable.dataSource = new MatMultiSortTableDataSource(this.sort, this.CLIENT_SIDE);
this.teamTable.nextObservable.subscribe(() => { this._tableEvent(); });
this.teamTable.sortObservable.subscribe(() => { this._tableEvent(); });
this.teamTable.previousObservable.subscribe(() => { this._tableEvent(); });
this.teamTable.sizeObservable.subscribe(() => { this._tableEvent(); });
進入AfterViewInit,因為它依賴於ViewChild,或者將setter放在ViewChild中以在html加載時觸發。
請嘗試了解angular life cycle fellow
,在查看您的代碼后,我分析了您依賴於ngOnInit()
方法的執行,但不幸的是它沒有發生,對嗎? 這是因為Angular Life Cycle fellow
,方法ngOnInit()
在組件加載時只執行一次,
因此,在您的情況下,您需要實現另一個angular life cycle method
,即OnChanges
,一旦您使用組件實現,它將強制您覆蓋它的ngOnChange(change: SimpleChanges)
方法,如下所示
每當您切換選項卡時,此ngOnChanges(changes: SimpleChanges)
方法都會執行,為此您需要將數據傳遞給子組件。
似乎您沒有將數據傳遞給子組件,可能是您擁有全局數據,或者您正在從子組件內的 api 獲取數據,不確定!
你能告訴我嗎,你是如何獲取子組件的數據的?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.