【问题标题】:Angular Filtering: Problem when i Clear the Search Box角度过滤:清除搜索框时出现问题
【发布时间】:2022-01-10 01:53:24
【问题描述】:

我有一个正在显示的对象列表,我添加了一个搜索框来过滤列,现在当我输入一个值时,它工作正常并且数据被过滤。问题是,当我清除搜索框时,我没有取回所有数据,我一直停留在我首先搜索的内容上,所以每次我想更改输入的值或获取整个列表时都必须刷​​新。

这是我的 Ts 代码:

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Facture } from '../model/facture.model';
import { FactureService } from '../services/facture.service';

@Component({
  selector: 'app-factures',
  templateUrl: './factures.component.html',
  styleUrls: ['./factures.component.css']
})
export class FacturesComponent implements OnInit {
  factures?: Facture[]; //un tableau de chînes de caractères
  cat?: number;

  constructor(private factureService: FactureService, private router: Router) {
    // this.factures = factureService.listeFacture();
  }

  deleteFacture(p: Facture) {
    let conf = confirm("Etes-vous sûr ?");
    if (conf)
      this.factureService.deleteFacture(p.idFacture).subscribe(() => {
        console.log("facture supprimé");
      });
    this.router.navigate(['factures']).then(() => {
      window.location.reload();
    });
  }
  
  search() {
    if (this.cat != null) {
      this.factures = this.factures?.filter(res => {
        return res.idFacture.toLocaleString().match(this.cat!.toLocaleString())
      });
    } else if (this.cat == null) {
      this.ngOnInit();
    }
  }


ngOnInit(): void {
  this.factureService.listeFacture().subscribe(prods => {
    console.log(prods);
    this.factures = prods;
  });

}

}

这是我的 HTML 代码:

<body >
<main role="main" class="container" >
<div  class="jumbotron" style="background-color: white;">
  <h2>Liste des Adhérents</h2>
  <input type="text" [(ngModel)]="name" (input)="Search()" />  
  <table class="table table-hover">
    <thead class="thead-light">
<tr>
   <th>Nom Complet</th>
   <th>Grade</th>
   <th>Poste</th>
   <th>Telephone</th>
   <th>E-mail</th>
   <th></th>
 </tr>
 </thead>

     <tr *ngFor="let item of adherents">
       <td>{{item.nomcomplet}}</td>
       <td>{{item.grade}}</td>
       <td>{{item.poste}}</td>
       <td>{{item.telephone}}</td>
       <td>{{item.email}}</td>
       <td><button [routerLink]="['/adherents/', item.id]" style="margin-right: 0.2em;" title="Details" class="btn-sm btn-secondary text-white"><i class="fa fa-eye"></i></button>
        <button [routerLink]="['/adherentEdit/', item.id]"
        style="margin-right: 0.2em;" title="Modifier" class="btn-sm btn-primary text-white"><i class="fa fa-edit"></i></button></td>
     </tr>
   </table>

   
</div>
</main>
</body>

请问如何修改 Search() 函数,以便在更改搜索框输入中的值时从数组中动态获取数据?

【问题讨论】:

  • 您正在过滤原始数组并将其分配回原始数组,因此这是意料之中的。您需要第二个数组来存储原始值。虽然我个人喜欢在模板中使用 formcontrol 和异步管道来过滤 observables。只是我的喜好。
  • 哦...this.factures 在哪里使用...?注意到刚才,您似乎在模板中使用了一个不相关的数组?

标签: angular filter


【解决方案1】:

你说:“当我清除搜索框时,我没有得到所有数据......” 您没有指定是否收到 0 件商品,或者您仍保留使用前一个过滤器收到的商品。

  1. 如果您使用与上一次搜索相同的项目,我猜您正在传递以搜索“cat”中的某些代码不是“null”但不是 null('' 或未定义,或其他东西),所以它不会进入第二个 if。

所以解决方案是在以下情况下删除第二个:

if (this.cat != null) {
      this.factures = this.factures?.filter(res => {
        return res.idFacture.toLocaleString().match(this.cat!.toLocaleString())
      });
    } else {
      this.ngOnInit();
    }

另一方面,如果您正在调用“onInit()”, 可能您的视图没有检测到更改并且没有刷新数组的值。 这是因为 Angular 的变更检测不关注数组/对象(通过引用传递),因此不会重新渲染它。

我猜这就是问题所在,您可以做一个快速测试,将“不纯”管道添加为 slice

<tr *ngFor="let item of adherents | slice:0">

EXTRA:也许这也与你的问题有关,虽然我不这么认为。无论如何,作为提示,我不会直接使用 ngOnInit 方法,它是 Angular 生命周期的一部分。

你可以将它的所有逻辑传递给一个函数,在 ngOnInit 中调用它,然后总是调用新函数而不是 ngOnInit。 像这样的:

ngOnInit(): void {
 this.getAndSetFactures()
}

getAndSetFactures() {
 this.factureService.listeFacture()
   .subscribe(prods => {
    console.log(prods);
    this.factures = prods;
  });
}

  search() {
    if (this.cat != null) {
      this.factures = this.factures?.filter(res => {
        return res.idFacture.toLocaleString().match(this.cat!.toLocaleString())
      });
    } else {
      this.getAndSetFactures();
    }
  }

【讨论】:

    【解决方案2】:

    发生这种情况是因为您在过滤时分配给包含所有数据的同一数组。

    我会通过引入第二个保存原始数据的变量和另一个保存过滤数据的数组来解决这个问题:

    export class FacturesComponent implements OnInit {
      factures?: Facture[]; //un tableau de chînes de caractères
      facturesFiltrèes: Facture[];
    
    
      ngOnInit(): void {
        this.factureService.listeFacture().subscribe(prods => {
          console.log(prods);
          this.factures = prods;
        });
      }
      
      search() {
        this.facturesFiltrèes = this.factures.filter(res => 
          !this.cat || res.idFacture.toLocaleString().match(this.cat!.toLocaleString()));
      }
    
    }
    

    从现在开始,在您需要显示搜索结果的地方使用facturesFiltrèes,而不仅仅是factures(因为这是我们为保持原始数据原始而保留的)。

    P.S.:请不要自己调用ngOnInit,这是一个Angular生命周期方法,框架本身只能调用一次。

    【讨论】:

    • 问题是,如果我像你说的那样使用facturesFiltrèes,什么都不会发生
    • 您应该在search 方法中将过滤后的数据分配给facturesFiltrèes
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-26
    • 2015-03-31
    • 1970-01-01
    • 2022-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多