Angular - 如何在@tusharghoshbd/ngx-datatable 高级搜索中解析 "Property does not exist on type 'never'"

Angular - How to resolve "Property does not exist on type 'never'" in @tusharghoshbd/ngx-datatable Advanced Search

在我的 Angular-13 项目中,我试图在 @tusharghoshbd/ngx-datatable

中实施高级搜索

我有这个代码:

接口:

export interface Merchant {
  id?: number;
  merchant_name?: string;
  account_number?: string;
  merchant_status?: number;
  created_date?: string;
}

服务:

  import { Merchant} from 'src/app/models/merchants.model';

  getAllMerchants(): Observable<Merchant[]> {
    return this.http.get<Merchant[]>(this.baseUrl + 'merchants');
  }

component.ts:

import { MerchantService } from 'src/app/services/merchant.service';
import { Merchant} from 'src/app/models/merchants.model';

export class MerchantsComponent implements OnInit {
  @ViewChild('idTpl', { static: true }) idTpl!: TemplateRef<any>;
  allMerchantList: any[] = [];
  data = [];
  dataBK = this.allMerchantList;
  options = {};
  columns: any = {};    
  constructor(
    private merchantService: MerchantService,
    ) { }

  ngOnInit(): void {
    this.loadDatatable();
    this.loadAllMerchants();
  }

  loadDatatable(){
    this.columns = [
      {
        key: 'id',
        title: '<div class="blue"><i class="fa fa-id-card-o"></i> SN.</div>',
        width: 60,
        sorting: true,
        cellTemplate: this.idTpl,
      },
      {
        key: 'merchant_name',
        title: '<div class="blue"><i class="fa fa-user"></i> Merchant</div>',
        width: 100,
        sorting: true,
      },
      {
        key: 'account_number',
        title: '<div class="blue"><i class="fa fa-envelope"></i> Account No.</div>',
        width: 100,
        sorting: true
      }
    ];
  }

  loadAllMerchants(){
    this.merchantService.getAllMerchants().subscribe({
      next: (res: any) => {
        this.allMerchantList = res.result;
        this.dataBK = this.allMerchantList;
      }
    })
  }

  onMerchantNameSearch(value: any)
  {
    this.data = this.dataBK.filter(row => row.merchant_name.toLowerCase().indexOf(value) > -1);
  }

  onAccountNumberSearch(value: any)
  {
    this.data = this.dataBK.filter(row => row.account_number.toLowerCase().indexOf(value) > -1);
  }
}

component.html:

<div class="col-sm-4 col-xs-6 col-6 ">
  <div class="form-group">
    <label for="merchant_Name">Merchant Name:</label>
    <input type="text" autocomplete="off" class="form-control" (input)="onMerchantNameSearch($event.target.value)" id="merchant_Name" placeholder="Merchant Name"/>
  </div>
</div>
<div class="col-sm-4 col-xs-6 col-6 ">
  <div class="form-group">
    <label for="account_number">Account No.</label>
    <input type="text" autocomplete="off" class="form-control" (input)="onMerchantNameSearch($event.target.value)" id="account_number" placeholder="Account Number"/>
  </div>
</div>

  <ngx-datatable tableClass="table table-striped table-bordered table-hover" [data]="allMerchantList" [columns]="columns" [options]="options">
    <ngx-caption>
      </div>
    </ngx-caption>

    <ng-template #addressTpl let-row let-rowIndex="rowIndex" let-columnValue="columnValue">

    </ng-template>
    <ng-template #idTpl let-rowIndex="rowIndex" let-row="row">
      {{rowIndex+1}}
    </ng-template>

  </ngx-datatable>

console.log(res);

给出:

"result":[
    {
        "id": 1,
        "merchant_name": "Appiah",
        "account_number": "332222",
        "merchant_status": 1,
        "created_date": "2022-01-24T12:51:08.19",
    },
    {
        "id": 2,
        "merchant_name": "Kwesi",
        "account_number": "554444",
        "merchant_status": 1,
        "created_date": "2022-01-25T16:43:41.873",
    },
    {
        "id": 3,
        "merchant_name": "fggffgfgfg",
        "account_number": "455654",
        "merchant_status": 1,
        "created_date": "2022-01-25T16:46:20.77",
    }
]

console.log(this.allMerchantList);

给出:

[
    {
        "id": 1,
        "merchant_name": "Appiah",
        "account_number": "332222",
        "merchant_status": 1,
        "created_date": "2022-01-24T12:51:08.19",
    },
    {
        "id": 2,
        "merchant_name": "Kwesi",
        "account_number": "554444",
        "merchant_status": 1,
        "created_date": "2022-01-25T16:43:41.873",
    },
    {
        "id": 3,
        "merchant_name": "fggffgfgfg",
        "account_number": "455654",
        "merchant_status": 1,
        "created_date": "2022-01-25T16:46:20.77",
    }
]

当我在高级搜索的输入字段中输入值时,我希望在@tusharghoshbd/ngx-datatable.

中得到结果

但在我这样做之前,我在组件中遇到了这个错误:

error TS2339: Property 'merchant_name' does not exist on type 'never'.

192 this.data = this.dataBK.filter(row => row.merchant_name.toLowerCase().indexOf(value) > -1);

我该如何解决这个问题?

谢谢

因为您正在将实例分配给 null。您应该先定义 属性 来初始化它。在 row 你试图访问 merchant_name 但它可能永远不存在或没有任何东西。

快速简便的解决方法可能是定义 dataBK 具有的内容。 dataBK: any[] = []; 如果我们不关心它有什么或者数据类型可能会改变,我们可以使用任何。

正确的方法是创建一个界面。 dataBK 持有什么?行数组。好的 - 什么样的行?我们在行对象中包含 merchant_name, account_number...。然后我们总是知道,dataBK 将保存一个数组或 Row 个对象。我们已经定义,Row 对象将具有要访问的此类属性。留在 ? 因为我不能 100% 确定它们会在那里被访问,也许你会这样做 - 如果你可以删除问号。

dataBK: Row[] = [];

interface Row {
id?: number;
merchant_name?: string;
account_number?: string;
merchant_status?: number;
created_date?: string;
}

也许不要使用 dot-notation 来获取匿名对象的 属性。可能是编译器认为这种情况是错误的。

onMerchantNameSearch(value: any)
{
    this.data = this.dataBK.filter(row => 
        row['merchant_name'].toLowerCase().indexOf(value) > -1);
}

onAccountNumberSearch(value: any)
{
    this.data = this.dataBK.filter(row => 
        row['account_number'].toLowerCase().indexOf(value) > -1);
}

如果您不想 运行 出现这样的错误(这似乎是 TypeScript 转换的一个小问题),那么您可以在 angular.json 中禁用“strictNullChecks”文件。那么“never”类型就不会存在了。

您的 MerchantService 可能不正确。 HttpClient.get 直接 returns 正文,除非您添加选项参数并设置“观察”-属性。所以尝试按如下方式更改订阅:

this.merchantService.getAllMerchants().subscribe((res: any) => {
    this.allMerchantList = res;
    this.dataBK = this.allMerchantList;
})

另请查看我的示例:https://stackblitz.com/edit/angular-rrdq9z?file=src/app/app.component.ts