Angular:搜索过滤器RXJS

发布于 2025-02-02 14:25:14 字数 2790 浏览 2 评论 0原文

我实现了它在“输入”按钮中查找的函数 但是我遇到了一个问题,我在那里有一个条件,我希望输入目前为空,以便将其误解并显示我的所有数据。

现在,一旦输入为空,我就写了一条消息“找不到”:

我希望的是,一旦输入为空,就会向我显示所有数据,如果它不是空的,则它将显示适当的数据,或者不存在然后找不到:

我的接口:

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

我的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:

<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;
      }
    }
  }

我的服务:

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 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":
enter image description here

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:
enter image description here

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:

<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)
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

俏︾媚 2025-02-09 14:25:14

我相信最大的错误是您忘了初始化有效posts ngoninit ,这解释了为什么您在开始时没有看到任何帖子:

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

如果您想显示全部空白搜索上的帖子,您可以检查搜索键单词是否为空字符串,如果是这样,则将您的有效posts设置为posts

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

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

应该就是这样!

如果您想进一步改进,我还有其他一些建议:

  1. 您无需使用两种方式数据绑定来进行这样的简单搜索,只需通过搜索关键字过滤ports完全好。
  2. 您不必创建ISEXISTS变量即可跟踪如果您有任何有效posts,因为它是一个数组,则可以检查其长度。
  3. 您可以创建一个模板来显示空的帖子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>

想要进一步采用它吗?

  1. 看看onpush更改检测以提高性能。
  2. 学习RXJS并实施访问搜索!

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(): 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:

    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.
  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.
  3. You can create a template to display the empty post 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.
  2. Learn RXJS and implement a debounce search!
夏末染殇 2025-02-09 14:25:14

我建议您用 keyup 替换输入事件

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

在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;
      }
    }

I suggest you to replace your input event, with 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) {

    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;
      }
    }

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文