Angular 2+ - 检查 Pipe 是不是返回原始列表的空子集

Posted

技术标签:

【中文标题】Angular 2+ - 检查 Pipe 是不是返回原始列表的空子集【英文标题】:Angular 2+ - check if Pipe returns an empty subset of original listAngular 2+ - 检查 Pipe 是否返回原始列表的空子集 【发布时间】:2016-09-01 05:13:32 【问题描述】:

我有一个要遍历的字符串列表,但我希望能够使用搜索词过滤它们。像这样:

<div *ngFor="#item in list | search: searchTerm"> item </div>

我的问题是:如何检查管道是否返回列表的空子集?

换句话说,如果没有字符串与搜索词匹配,我想显示一条消息:“不匹配”。

【问题讨论】:

【参考方案1】:
<div *ngIf="(list | search: searchTerm).length === 0">
  "No matches"
</div>
<div *ngFor="#item in list | search: searchTerm"> item </div>

或者,您可以修改管道以返回指示列表为空的特定标记

@Pipe(
  name: 'search'
)
export class SearchPipe 

  transform(value, searchTerm) 
    let result = ...
    if(result.length === 0) 
      return [-1];
    
    return result;
  

<ng-container *ngFor="let item of list | search: searchTerm">
  <div *ngIf="item === -1">"No matches"</div>
  <div *ngIf="item !== -1"> item </div>
</ng-container>

【讨论】:

太棒了!我认为第二种解决方案是最好的,因为在第一种解决方案中,您必须遍历列表两次,对吧? 没有更好的办法吗? @ValdemarEdvardSandalRolfsen 那么在第二个解决方案中,如果 item 对象上有多个字段会发生什么?比如, item.name item.age 等等? @Rexford 我不明白这与问题或我的答案有什么关系,或者问题可能是什么。 谢谢!它节省了我很多时间。 :-)【参考方案2】:

可以利用依赖注入到管道中。你可以注入组件:

然后你可以在它上面设置一个属性来通知这个:

@Pipe(
  name: 'search'
)
export class SearchPipe 
  constructor(@Inject(forwardRef(() => SomeComponent)) private comp:SomeComponent) 

  

  transform(value) 
    var filtered = value.map((v) => v-1);
    this.comp.isEmpty = (filtered.length === 0);
    return filtered;
  

主要缺点是您在组件内链接管道。优点是过滤执行一次。

【讨论】:

【参考方案3】:

这是我从@Günter Zöchbauer 修改的代码

<div  *ngFor="let filter_list of list | FilterItem" >
    <div *ngIf=" filter_list == -1 " class="alert alert-info">No item found</div>    
    <div *ngIf="filter_list !== -1" *ngFor="let item of filter_list  ; let i = index;" >
         item 
    </div>
</div>

管道代码

@Pipe(
  name: 'FilterItem'
)
export class FilterItem 

  transform(list, args?) 
       let result = ...; 
       if ( result && result.length > 0 )
          return [ result ];
       else
          return [ -1 ];
       
  

【讨论】:

【参考方案4】:

实现此目的的另一种方法是检查 html 元素中的子元素,或者在我的情况下检查表中的行。

<table #myTable>
  <tr *ngFor="let item of list | somePipe : searchText">
      <td> item.name </td>
  </tr>
</table>

<p *ngIf="!myTable.rows.length">No results</p>

【讨论】:

如果 #element 不是表格(例如 div),则使用 element.children.length 这比复制过滤器代码或返回任意值要好得多,因为接受的答案表明 不再起作用 - 给出 ExpressionChangedAfterItHasBeenCheckedError 错误 - 至少在 Angular 4.4.5 上【参考方案5】:

如果您的目的只是渲染一个元素,而不是使用 CSS 查询它自己,我只是放弃Günter Zöchbauer 代码。

<ng-container *ngFor="let item of list | search: searchTerm">
  <div *ngIf="item !== -1"> item </div>
  <div class="empty">"No matches"</div>
</ng-container>

CSS

div.empty 
  display:none;

div.empty:first-child 
  display:block;

.list div.empty 
  display: none;


.list div.empty:first-child 
  display: block;
<h4>If you hava record to display than</h4>
<div class="list">
  <div>The first record.</div>
  <div>The second record.</div>
  <div>The third record.</div>
  <div class="empty">"No matches"</div>
</div>
<br>
<h4>If no record to show</h4>
<div class="list">
  <div class="empty">"No matches"</div>
</div>

【讨论】:

【参考方案6】:

这是我能生产的最干净的解决方案。

@Pipe(
  name: 'search'
)
export class SearchPipe 

  transform(value, searchTerm) 
    let result = ...
    if(result.length === 0) 
      return [undefined];
    
    return result;
  

通过返回[undefined],DOM 中的检查更加简洁易读。

<ng-container *ngFor="let item of list | search: searchTerm">
  <div *ngIf="!item">"No matches"</div>
  <div *ngIf="item"> item </div>
</ng-container>

【讨论】:

【参考方案7】:

Angular 现在支持带有变量的 ngIf,您可以将管道结果分配给一个新变量,然后在 if 块内进行循环

<ng-container *ngIf="search: searchTerm as results; else noItems">
 <!-- else is for cases where search:Search term is undefined or null  -->

    <div *ngFor="let item of results">item</div>

    <!-- the case where the pipe returns an empty array  -->
    <div *ngIf="!result.length">no items match the search</div>
</ng-container>
<ng-template #noItems>searching...</ng-template>

【讨论】:

最干净的解决方案恕我直言

以上是关于Angular 2+ - 检查 Pipe 是不是返回原始列表的空子集的主要内容,如果未能解决你的问题,请参考以下文章

angular6之pipe管道

Angular 2. *ngFor 的问题,当我使用 Pipe 时

4Angular2 pipe

angular 2 custom sort pipe 请帮帮我

angular之自定义管道

检查用户是不是在 Angular 2 中滚动到底部