1

我试图使用 Angular Material 包重新创建一个垫表。mat-table 示例最近得到了大规模改进,这令人惊叹。他们在此处提供了这个示例,其中包含排序和过滤功能

我试图在我自己的应用程序的上下文中重现这一点,在 stackblitz here的一个最小示例中使用虚拟数据。

该表显示并填充了数据,但是一旦我输入多个字母,过滤器方法似乎错误地删除了所有条目,即使是不应该删除的条目。

我在这里能想到的一个区别是,在我的示例中,我在声明 dataSource: 时使用了一个类dataSource: MatTableDataSource<Match>;,而在 Angular 人员提供的示例中,它是一个接口:dataSource: MatTableDataSource<UserData>;

不过,这很可能是一个红鲱鱼,因为我尝试使用界面而不是成功。非常感谢这里的任何帮助。

4

4 回答 4

8
于 2019-09-08T04:52:28.767 回答
3

通常,过滤器的工作方式是将对象的第一级数据序列化为字符串,然后快速检查字符串是否包含。这不适用于深层物体。所以你不能依赖默认过滤,需要提供一个filterPredicate.

文件中它说

要覆盖默认过滤行为,filterPredicate可以设置一个自定义函数,该函数接受一个数据对象和过滤字符串,如果数据对象被认为是匹配的,则返回 true。

仅按位置过滤的示例:

    this.dataSource.filterPredicate = (match: Match, filter: string) => {
      return match.matchDeets.location.toLowerCase().includes(filter);
    };
于 2019-09-07T23:59:22.463 回答
1

如其他答案中所述,该filter功能仅过滤一层深度。不过,在您的问题中,我认为您的数据一开始就没有任何原因。在您的模板中,您只显示来自 的项目matchDeets,所以为什么不直接matchDeets用作您的dataSource. 这将使您的过滤器功能再次工作。

在您的组件中,只需将其更改dataSource为以下内容。

dataSource: MatTableDataSource<MatchDetails>;

// Other code goes here

this.dataSource = new MatTableDataSource(matchArray.map(match => match.matchDeets));

此更改将是不可变的,因此matchArray仍将包含您班级中的其他数据。由于您的模板似乎并不关心它们,我们将只传递给dataSouce我们需要的东西,即matchDeets.

现在在您的模板中,您只需要将显示值更新为{{entry.matchDeets.rank}}to {{entry.rank}}{{entry.matchDeets.weightClass}}to{{entry.weightClass}}等等。

您的过滤器功能现在可以工作了。这是StackBlitz上的一个工作示例。

于 2019-09-08T05:55:25.883 回答
0

为了允许任何类型的数组,MatTableDataSource 在模型中应该如下所示。

  dataSource = new MatTableDataSource<any>();

要清除过滤器:

this.dataSource.filter="";

要查看要显示的内容:

this.dataSource.data

从输入元素挂钩 keydown 和 keyup 开始过滤过程

<input id='search' #search  matinput type='text' (keydown)="onKeyDown(search,$event)" (keyup)='onSearchChanged(search, $event)' />

//this catches the backspace
onKeyDown(searchInput, event) {
      if (event.key === "Backspace") {
         this.filter = this.dataSource.filter = searchInput.value;
         this.cdf.detectChanges();
      }
   }

//this changes the filter as they type in the input field
onSearchChanged(search, event) {
      this.filter = search.value;
      this.dataSource.filter = this.filter;
      this.cdf.detectChanges();
   }

如果没有显示任何内容,则必须确保已设置列标题和列 ID。

于 2019-08-28T22:01:34.870 回答