簡體   English   中英

Angular 子組件表

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM