Angular:试图将我的功能变成RXJS

发布于 2025-02-02 12:06:24 字数 522 浏览 3 评论 0 原文

我的功能已实现并正常工作 我想在RXJS目录中使用过滤器将其rxjs置于rxjs目录中,并包含

并使用subscribe更新

  posts: Post[] = [];
   validPosts: Post[] = [];
   authorName: string = "";

这是我的功能:

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.includes(this.searchName)
    );
  }

I have a function that is implemented and works properly
I want to make it rxjs with filter in rxjs directory use both pipe and includes

And update with subscribe

  posts: Post[] = [];
   validPosts: Post[] = [];
   authorName: string = "";

this is my function:

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.includes(this.searchName)
    );
  }

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

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

发布评论

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

评论(1

_畞蕅 2025-02-09 12:06:24

要使用输入字段构建搜索,请将输入元素绑定到 @viewchild

<label>Search Posts </label>
<div>
  <input #search type="text" [value]="filterInput" />
</div>
export class AppComponent implements OnInit, AfterViewInit, OnDestroy {

  @ViewChild('search', { static: true }) search: ElementRef;

  private subscription: Subscription;

  public posts$: Observable<Post[]>;
  public filterInput: string = '';
  public errorMessage: string = '';

  constructor(
    private router: Router,
    private route: ActivatedRoute,
    private appService: AppService
  ) {}

  ...

}

AfterViewInit 中,您可以在元素的事件中添加一个可观察到的。通过管道,您地图事件到其值。您添加了 debouncetime ,因此可观察到的发射不会太频繁,并且只能收听更改trough 独特的nuntilChanged

在订阅本身中,您可以根据输入来检查输入值并更改URL queryparams

ngAfterViewInit() {
  this.subscription = fromEvent(this.search.nativeElement, 'keyup')
    .pipe(
      map((event: KeyboardEvent) => (event.target as HTMLInputElement).value),
      debounceTime(500),
      distinctUntilChanged()
    )
    .subscribe((filter) => {
      const queryParams = filter ? { queryParams: { filter } } : undefined;
      this.router.navigate(['.'], {
        relativeTo: this.route,
        ...queryParams,
      });
    });
}

oninit 中,您 switchmap 可观察到的 queryparams 到一个新观察的可观察到,该可观察到,该可观察到,该可观察到,通过服务从数据库中获取过滤后的帖子。在窗口上,刷新URL的过滤器查询也将设置为输入值。

private fetchPosts() {
  this.posts$ = this.route.queryParams
    .pipe(
      switchMap((params) => {
        if (params.filter) this.filterInput = params.filter;
        return this.appService.fetchPosts(params.filter);
      })
    )
    .pipe(
      catchError((err) => {
        this.errorMessage = err;
        return EMPTY;
      })
    );
}

ngOnInit() {
  this.fetchPosts();
}

为了显示内容,您可以通过HTML中的 async 管道订阅可观察到的。

<div *ngIf="posts$ | async as posts; else loadingOrError">
  <div *ngIf="!posts.length">
    <h3>No posts found</h3>
  </div>
  <div *ngFor="let post of posts">
    <b>{{ post?.content }}</b>
    <br/>
    <i>
      by <b>{{ post?.authorName }}</b> at
      <b>{{ post?.date | date: 'dd MMMM YYYY' }}</b>
    </i>
    <hr />
  </div>
</div>

<ng-template #loadingOrError>
  <span *ngIf="errorMessage; else loading">
    An error occured while loading the posts: {{ errorMessage }}
  </span>
  <ng-template #loading> ...loading... </ng-template>
</ng-template>

State Management,使用RXJS | url vs本地客户端状态

To build a search using an input field, you bind the input element to a @ViewChild.

<label>Search Posts </label>
<div>
  <input #search type="text" [value]="filterInput" />
</div>
export class AppComponent implements OnInit, AfterViewInit, OnDestroy {

  @ViewChild('search', { static: true }) search: ElementRef;

  private subscription: Subscription;

  public posts$: Observable<Post[]>;
  public filterInput: string = '';
  public errorMessage: string = '';

  constructor(
    private router: Router,
    private route: ActivatedRoute,
    private appService: AppService
  ) {}

  ...

}

In the AfterViewInit, you add an observable to the keyup event of the element. Through a pipe, you map the event to its value. You add a debounceTime so the observable doesn't emit too often, and you only listen to changes trough distinctUntilChanged.

Within the subscription itself, you check the input value and change the url queryParams based upon the input.

ngAfterViewInit() {
  this.subscription = fromEvent(this.search.nativeElement, 'keyup')
    .pipe(
      map((event: KeyboardEvent) => (event.target as HTMLInputElement).value),
      debounceTime(500),
      distinctUntilChanged()
    )
    .subscribe((filter) => {
      const queryParams = filter ? { queryParams: { filter } } : undefined;
      this.router.navigate(['.'], {
        relativeTo: this.route,
        ...queryParams,
      });
    });
}

During OnInit, you switchMap the observable of the route's queryParams to a new observable which will fetch the filtered posts from your database through the service. Upon a window refresh the filter query from the url will also be set as the input value.

private fetchPosts() {
  this.posts$ = this.route.queryParams
    .pipe(
      switchMap((params) => {
        if (params.filter) this.filterInput = params.filter;
        return this.appService.fetchPosts(params.filter);
      })
    )
    .pipe(
      catchError((err) => {
        this.errorMessage = err;
        return EMPTY;
      })
    );
}

ngOnInit() {
  this.fetchPosts();
}

In order to show the content, you subscribe to the observable through an async pipe within the html.

<div *ngIf="posts$ | async as posts; else loadingOrError">
  <div *ngIf="!posts.length">
    <h3>No posts found</h3>
  </div>
  <div *ngFor="let post of posts">
    <b>{{ post?.content }}</b>
    <br/>
    <i>
      by <b>{{ post?.authorName }}</b> at
      <b>{{ post?.date | date: 'dd MMMM YYYY' }}</b>
    </i>
    <hr />
  </div>
</div>

<ng-template #loadingOrError>
  <span *ngIf="errorMessage; else loading">
    An error occured while loading the posts: {{ errorMessage }}
  </span>
  <ng-template #loading> ...loading... </ng-template>
</ng-template>

State management, using RxJS | URL vs local client state

StackBlitz | Filter through RxJS

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