【问题标题】:Angular How to put a html component after a dependent component?Angular 如何在依赖组件之后放置一个 html 组件?
【发布时间】:2019-10-03 20:50:42
【问题描述】:

我正在尝试使用 Angular-Material 分页器。在 html 中,寻呼机出现在它适用的列表之后(用户期望的位置)。

这是它的样子(数据只是组件中的一个数组属性。它工作正常。这大约是 *ngFor 取决于分页器)

<mat-list *ngIf="Data">
  <mat-list-item *ngFor="let item of Data.slice(
                        dataPager.pageIndex * dataPager.pageSize, 
                        (dataPager.pageIndex + 1) * dataPager.pageSize
  )">
    {{item.name}}
  </mat-list-item>
  <mat-paginator #dataPager [length]="Data.length"
                            [pageSize]="10"
                            [pageSizeOptions]="[5, 10, 25, 50, 100]">
  </mat-paginator>
</mat-list>

然而这给了我一个可怕的错误

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngForOf: '. Current value: 'ngForOf: [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]'.

严格来说,一切似乎都正常,但我根本不想得到这个错误。如果将分页器放在*ngFor 之前,我不会收到此错误,但分页器不在页面上我想要的位置。那么如何确保分页器组件在基于它的*ngFor 组件之前被初始化,即使分页器位于页面下方?

【问题讨论】:

  • 在模板Data.slice(dataPager.pageIndex * dataPager.pageSize, (dataPager.pageIndex + 1) * dataPager.pageSize 中调用函数不是一个好主意。将其存储在成员属性中。例如*ngFor="let item of slicedData"
  • @Exomus 成员属性是什么意思?您是指组件中的属性吗?
  • 在你的 ts 文件中声明一个 slicedData = Data.slice(dataPager.pageIndex * dataPager.pageSize,(dataPager.pageIndex + 1) * dataPager.pageSize) 并在你的模板中调用它。这将避免每次重新生成模板时,Angular 都会调用该函数。编辑:您需要明智地将this 放置在 TS 中
  • @Exomus 我刚刚遇到了slice pipe。管道是否更好或与调用切片基本相同?
  • 切片管道是impure 管道。这意味着它在变化检测的每个周期都被调用。它与仅在引用更改时调用的纯管道不同(例如,当数组中存在深度突变时,不会触发纯管道)。该管道基于 Javascript API 的Array.prototype.slice()。因此,在第一个近似值中,它是相同的。 (但更优雅的方式)。 编辑:注意不纯的管道会使用大量资源破坏用户体验

标签: angular angular-material


【解决方案1】:

我认为您不能将 mat-list-item 循环长度基于 dataPager 值本身。您可能需要使用它触发的事件来重新计算列表视图内容。您可以使用相同的起始页面大小来初始化两者。

https://material.angular.io/components/paginator/api#PageEvent

【讨论】:

    【解决方案2】:

    我最终调整了条件,并将分页器移动到列表之外,以便使用初始页面创建分页器,然后在 ngAfterViewInit() 中初始化馈送数据之前,ngFor 不会运行。至少它可以防止初始页面错误。如果 Data 未初始化,我将分页器的默认长度更改为 0,这样它就不必等待数据。

    <mat-list *ngIf="Data">
      <mat-list-item *ngFor="let item of Data.slice(
                            dataPager.pageIndex * dataPager.pageSize, 
                            (dataPager.pageIndex + 1) * dataPager.pageSize
      )">
        {{item.name}}
      </mat-list-item>
    </mat-list>
    <mat-paginator #dataPager [length]="(Data)? Data.length : 0"
                              [pageSize]="10"
                              [pageSizeOptions]="[5, 10, 25, 50, 100]">
    </mat-paginator>
    

    【讨论】:

    • 请注意,*ngIf 可以根据这篇文章破坏 MatPaginator:stackoverflow.com/questions/56028775/… 参考您的问题代码,首选 [隐藏]。在这里,您的 MatPaginator 不在 ngIf 条件范围内,所以很好
    猜你喜欢
    • 2020-04-27
    • 2016-09-15
    • 2016-09-10
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-13
    相关资源
    最近更新 更多