#javascript #angular #typescript
Вопрос:
У меня есть 2 компонента , которые являются компонентами A и B, в компоненте A я назвал дочерний компонент, который является компонентом B, представляющим собой таблицу селектора управления приложениями(дочерний компонент).
Если я переключу вкладку на Команды, она должна отображать дочерний компонент, который является управлением командами приложений. Прямо сейчас он смог отобразить интерфейс дочернего компонента , но не смог отобразить данные дочернего компонента, было вызвано управление командой приложений, но оно не отображало данные. ngOnInit управления командой приложений также не отображался и не вызывался
Я также добавил журнал консоли в ngOnInit дочернего компонента, который является управлением командой приложений, но ngOnInit не инициализировался
В чем, по-видимому, проблема с кодом ? почему, когда я вызываю приложение дочернего компонента-управление командой, оно не отображало данные и даже не вызывало 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>
#Компонент A вкладка переключения код 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 child component app-team-management code
@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 amp;amp; 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>
Комментарии:
1.
app-team-management
является ли дочерний компонент иngOnInit
не запускается? никаких ошибок?2. Да , он даже не регистрировал журнал консоли , который я поместил, но он отображал шаблон, как вы видите на скриншоте
3. но когда я меняю элементы на странице или нажимаю сортировку , загружаются данные, но сначала или при инициализации они не загружали данные, сэр
Ответ №1:
Вкладка Mat обычно предварительно загружает все компоненты, что означает, что ваш ngOnInit должен быть запущен задолго до того, как вы нажмете на вторую вкладку. это может означать, что он пытается получить данные, которых еще не существует. Сначала я бы попытался лениво загрузить ваш дочерний компонент, добавив ng-шаблон, который должен исправить запуск 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, или поместите сеттер в ViewChild для запуска при загрузке html.
Комментарии:
1. Я попробовал этот ответ , сэр, но это не решило проблему, также с этим решением шаблон даже не отображался, ошибок нет, также я проверил журналы.
Ответ №2:
Пожалуйста , попытайтесь понять angular life cycle fellow
, после просмотра вашего кода я проанализировал, что вы зависите от выполнения ngOnInit()
метода, но, к сожалению, этого не происходит, верно? это связано с тем Angular Life Cycle fellow
, что метод ngOnInit()
выполняется только один раз при загрузке компонента,
Поэтому в вашем случае вам нужно реализовать другой angular life cycle method
, который OnChanges
, как только вы реализуете свой компонент, заставит вас переопределить его ngOnChange(change: SimpleChanges)
метод, как показано ниже
Всякий раз, когда вы переключаете вкладку, этот ngOnChanges(changes: SimpleChanges)
метод будет выполняться, для этого вам нужно передать данные дочернему компоненту.
Похоже, вы не передаете данные дочернему компоненту! возможно, у вас есть глобальные данные или вы извлекаете данные из api в дочернем компоненте, не уверен!
Не могли бы вы, пожалуйста, сообщить мне, как вы получили данные для дочернего компонента?