简体   繁体   English

Angular:搜索过滤器 rxjs

[英]Angular: search filter rxjs

I implement a function that it looks for in the input button by name But I have a problem I made a condition there that I want the input to be empty at the moment so it will get false and display all my data.我实现了一个函数,它按名称在输入按钮中查找但是我有一个问题,我在那里做了一个条件,我希望输入现在为空,所以它会变为假并显示我的所有数据。

Right now as soon as the INPUT is empty I wrote a message "not found":现在,只要 INPUT 为空,我就写了一条消息“未找到”: 在此处输入图像描述

What I want it to be is that as soon as the input is empty it will show me all the data and if it is not empty then it will show me the appropriate data or if it does not exist then it will not be found:我想要的是,一旦输入为空,它将向我显示所有数据,如果它不为空,那么它将向我显示适当的数据,或者如果它不存在,那么它将找不到: 在此处输入图像描述

My interface:我的界面:

export interface Post{
    id:number,
    date: Date,
    authorName:string,
    content:string;
}

My seedDate:我的种子日期:

  createDb() {
    const posts: Post[] = [
      {id:1,authorName:"Daniel",content:"Amazon’s Garage Delivery Service"
      ,date:new Date('11/12/20')
    },
      {id:2,authorName:"Omer",content:"Jake From State Farm "
      ,date:new Date('12/20/21')},
      {id:3,authorName:"Lior",content:"The General"
      ,date:new Date('02/01/22')},
      {id:4,authorName:"Tomer",content:"Spotify’s Wrapped "
      ,date:new Date('11/11/20')},
    ];
    return {posts};

html: html:

<input
  type="search"
  (input)="SearchPostsByName($event)"
  [(ngModel)]="authorName"
/>
<div *ngFor="let post of validPosts">
  <ng-container *ngIf="isExists">
    The name of the author is <b>{{ post?.authorName }}</b> with content
    <b>{{ post?.content }}</b> and released it on the date
    <b>{{ post?.date }}</b>
  </ng-container>
</div>
<br>

typescript:打字稿:

posts: Post[] = [];
   authorName = "";
   content = "";
   date = new Date();
   isExists = false;
   validPosts: Post[] = [];
   Search:string=''; 

  constructor(private postService: PostService) { }

  ngOnInit(): void {
    this.postService.getPosts().subscribe((posts)=> {
      this.posts = posts;
    });
  }
  
  SearchPostsByName($event : Event) {
    console.log($event);
    if (this.authorName) {
      this.validPosts = this.posts.filter((value) => value.authorName === this.authorName!); 
      if (this.validPosts.length > 0
      ) {
        console.log('found');
        this.isExists = true;
      } else {
        this.isExists = false;
      }
    }
  }

My service:我的服务:

export class PostService {

  private postsUrl = 'api/posts';

  constructor(private http: HttpClient) { }

  getPosts(): Observable<Post[]> {
    return this.http.get<Post[]>(this.postsUrl);
  }

  addPost(post: Post): Observable<Post> {
    let httpOptions = {
      headers: new HttpHeaders({'Content-Type':'application/json'})
    };
    
    return this.http.post<Post>(this.postsUrl, post, httpOptions)
  }

I believe the biggest mistake is that you forgot to initialize your validPosts inside ngOnInit , which explains why you're not seeing any posts in the beginning:我认为最大的错误是您忘记在ngOnInit validPosts这解释了为什么您一开始没有看到任何帖子:

  ngOnInit(): void {
    this.postService.getPosts().subscribe((posts) => {
      this.posts = posts;
      this.validPosts = posts;
    });
  }

If you want to display all the posts on an empty search, you can check if the search key word is an empty string, if so set your validPosts to posts :如果您想在空搜索中显示所有帖子,您可以检查搜索关键字是否为空字符串,如果是,请将您的validPosts设置为posts

    const searchKey = ($event.target as HTMLInputElement).value;

    if (searchKey === '') {
      this.validPosts = this.posts;
      return;
    }

That's should be it!应该就是这样!

Here are some other suggestions that I have if you want to improve this even further:如果您想进一步改进,我还有一些其他建议:

  1. You do not need to use two way data binding for a simple search like this, simply filtering the posts by the search keyword would be perfectly fine.对于这样的简单搜索,您不需要使用双向数据绑定,只需按搜索关键字过滤posts就可以了。
  2. You don't have to create the isExists variable just to track if you have any validPosts , since it's an array, you can check its length instead.您不必创建isExists变量来跟踪是否有任何validPosts ,因为它是一个数组,您可以检查它的长度。
  3. You can create a template to display the empty post html您可以创建一个模板来显示空的帖子 html
  SearchPostsByName($event: Event) {
    const searchKey = ($event.target as HTMLInputElement).value;

    if (searchKey === '') {
      this.validPosts = this.posts;
      return;
    }

    this.validPosts = this.posts.filter(
      (value) => value.authorName === searchKey
    );
  }
<input type="search" (input)="SearchPostsByName($event)" />
<ng-container *ngIf="validPosts.length; else emptyPostTpl">
  <div *ngFor="let post of validPosts">
    The name of the author is <b>{{ post?.authorName }}</b> with content
    <b>{{ post?.content }}</b> and released it on the date
    <b>{{ post?.date }}</b>
  </div>
</ng-container>
<br />

<ng-template #emptyPostTpl>
  <span style="font-size: 1rem; font-weight: bold; display: block"
    >No post found</span
  >
</ng-template>

Want to take it even further?想要更进一步?

  1. Take a look at onPush change detection to improve performance.看看onPush更改检测以提高性能。
  2. Learn RXJS and implement a debounce search!学习 RXJS 并实现去抖动搜索!

I suggest you to replace your input event , with keyup .我建议你用keyup替换你的输入事件

 <input type="search" (keyup)="SearchPostsByName($event)" [(ngModel)]="authorName" />

In SearchPostsByName($event), query event$.target.value to check if there's any input:在 SearchPostsByName($event) 中,查询event$.target.value以检查是否有任何输入:

 SearchPostsByName($event : Event) { if(!$event.target.value.length) { return; } if (this.authorName) { this.validPosts = this.posts.filter((value) => value.authorName === this.authorName!); if (this.validPosts.length > 0 ) { console.log('found'); this.isExists = true; } else { this.isExists = false; } }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM