【问题标题】:Angular4: ERROR TypeError: Cannot read property 'length' of undefined while accessing length propertyAngular4:错误类型错误:访问长度属性时无法读取未定义的属性“长度”
【发布时间】:2018-04-25 18:38:54
【问题描述】:

我正在处理 angular 4 的分配,我是新手,我正在为 mat-table 应用分页,在其中遇到了一些问题,而我正在将数据打印到控制台,它显示如下

当我尝试应用 dataSource.data.length 时,出现以下错误。

WellComponent.html:57 ERROR TypeError: Cannot read property 'length' of undefined
    at Object.View_WellComponent_0._co [as updateDirectives] (WellComponent.html:60)
    at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:13075)
    at checkAndUpdateView (core.es5.js:12255)
    at callViewAction (core.es5.js:12620)
    at execComponentViewsAction (core.es5.js:12552)
    at checkAndUpdateView (core.es5.js:12261)
    at callViewAction (core.es5.js:12620)
    at execEmbeddedViewsAction (core.es5.js:12578)
    at checkAndUpdateView (core.es5.js:12256)
    at callViewAction (core.es5.js:12620)

我可以在这方面获得帮助吗,我应该如何访问该长度属性。

组件:

    import { MatPaginator } from '@angular/material';
    import { DataSource } from '@angular/cdk/collections';
    import { Component, OnInit,ViewChild,ChangeDetectorRef } from '@angular/core';
    import { WellService } from '../services/well.service';
    import { Well } from '../well/well';
    import {  Observable  } from 'rxjs/Rx';
    import { BehaviorSubject } from  'rxjs/BehaviorSubject';
    import 'rxjs/add/operator/startWith';
    import 'rxjs/add/observable/merge';
    import 'rxjs/add/operator/map';



    @Component({
      selector: 'app-well',
      templateUrl: './well.component.html',
      styleUrls: ['./well.component.css'],
      providers:[WellService]
    })



    export class WellComponent implements OnInit {
      title = 'Wells';
      header:string;  
      displayedColumns = ['active', 'company', 'country', 'well','wellbore'];
      public dataSource: WellDataSource | any;
      obs:any;

      @ViewChild(MatPaginator) paginator : MatPaginator;

      constructor(private wellService:WellService) {

        this.header='assets/images/BHI_header_logo_bd.png'  

       }

       ngOnInit() {
        this.obs = this.wellService.getWells();
        this.dataSource = new WellDataSource(this.obs, this.paginator);

      }

      }

      export class WellDataSource extends DataSource<any> {

      constructor(private _obs: any, private _paginator: MatPaginator) {
        super();
      }

      connect(): Observable<any[]> {
        const displayDataChanges = [
          this._obs,
          this._paginator.page,
        ];

        return this._obs.flatMap(x => {
          return Observable.merge(...displayDataChanges).map(() => {
            const data = x.slice();
            console.log(data);
            const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
            console.log(startIndex);
            console.log(this._paginator.pageSize)
            console.log(this._obs);
            console.log(x.slice());
            return data.splice(startIndex, this._paginator.pageSize);
          });
        })
      }

        disconnect() {}
      }


**HTML:**

<div>
  <div class="image"><img  [src]="header" ></div>

  <div class="w3-display-left">
  <nav>
     <li><a routerLink="/wells" routerLinkActive="active">My Wells</a></li>
      <li><a routerLink="/dev" routerLinkActive="active">Well Management</a></li>
      <li><a routerLink="/dev" routerLinkActive="active">Admin Tools</a></li>
  </nav>
  <div class="w3-display-right">
    <button mat-button>Reset</button>
    <button mat-button>Refresh</button>
    <button mat-button>View Wireline</button>
    <button mat-button>Chat</button>
    <button mat-button>View Seismic</button>
    <button mat-button>Alerts</button>

  </div>


  <br>
  <br>
   <div> 
        <mat-table #table [dataSource]="dataSource">
    <!-- Active -->
    <ng-container matColumnDef="active">
      <mat-header-cell *matHeaderCellDef> Active </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.active}} </mat-cell>
    </ng-container>

    <!-- Company -->
    <ng-container matColumnDef="company">
      <mat-header-cell *matHeaderCellDef> Company </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.company}} </mat-cell>
    </ng-container>

    <!-- Country -->
    <ng-container matColumnDef="country">
      <mat-header-cell *matHeaderCellDef>Country</mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.country}} </mat-cell>
    </ng-container>

    <!-- Well -->
    <ng-container matColumnDef="well">
      <mat-header-cell *matHeaderCellDef> Well </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.well}} </mat-cell>
    </ng-container>


        <!-- Wellbore -->
        <ng-container matColumnDef="wellbore">
          <mat-header-cell *matHeaderCellDef> Wellbore </mat-header-cell>
          <mat-cell *matCellDef="let row"> {{row.wellbore}} </mat-cell>
        </ng-container>

    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
  </mat-table>
  <mat-paginator #paginator
  [length]="dataSource.data.length"
  [pageIndex]="0"
  [pageSize]="25"
  [pageSizeOptions]="[5, 10, 25, 100]">
</mat-paginator>
</div>
</div> 
<div>    
    <router-outlet></router-outlet>
    </div>

【问题讨论】:

  • 也发布代码
  • 你的意思是我的组件和html吗?
  • 是的,我们会帮你的
  • 我已将它们添加到那里,您现在可以查看

标签: angular pagination angular-material


【解决方案1】:

错误是因为您试图在数据可用之前访问数据

尝试使用安全运算符:

dataSource.data?.length

在构造函数中进行一些初始化

dataSource.data = [];

根据您的代码将 [length]="dataSource.data.length" 更改为 [length]="obs.data?.length" ,如下所示:

<mat-paginator #paginator
  [length]="obs.data?.length"
  [pageIndex]="0"
  [pageSize]="25"
  [pageSizeOptions]="[5, 10, 25, 100]">
</mat-paginator>

【讨论】:

  • 尝试了第一个条件,错误消失了,但分页没有按预期进行,它显示 1-25 of 0,只有第一页。
  • @SaiCharan,那一定是因为编码的其他部分,如果你能创建一个问题的 plunkr 会更好,这样更多的开发人员可以帮助你并且非常快速,你会请接受并投票赞成答案?
  • 你确定我会尝试创建 plunker
  • @SaiCharan,请查看我更新的答案,这可能会解决您的其他问题
  • @SaiCharan,那么你必须为此创建一个 plunkr
【解决方案2】:

初始化数组导致错误消失,但表中的数据永远不会更新——它是空白的。添加问号(即 dataSource.data?.length)不起作用,因为在其他地方预计不会未定义。

某个孩子告诉我尝试一个 BehaviorSubject。它们是始终具有价值的 Observable。当您订阅时,您将获得最新的价值。他们也是观察者,你可以告诉他们下一个值是什么。在此处阅读更多内容。

http://reactivex.io/rxjs/manual/overview.html#behaviorsubject

我将 dataSource.data 设为 BehaviorSubject,按照孩子告诉我的方式,初始值 [] 然后在值更改时告诉它(通过 next())。

而且,因为我正在进行排序和分页,所以我必须更新该代码以使用 this.data.getValue() 而不是 this.data。

【讨论】:

    【解决方案3】:

    我通过结合两种方法解决了这个问题:

    a) 安全操作员

    [length]="dataSource.data?.length"

    b) 正确初始化数据源(避免切片错误)

    ngOnInit() {
      this.dataSource = new EmplTblDataSource(this.paginator, this.sort);
      this.dataSource.data=[];
    }
    

    然后,我更新OnChanges方法中的表格内容

    【讨论】:

      猜你喜欢
      • 2017-11-25
      • 2019-05-13
      • 1970-01-01
      • 2022-11-12
      • 2015-05-08
      • 2020-06-02
      • 1970-01-01
      • 2013-11-24
      相关资源
      最近更新 更多