Angular - Rxjs Observable - реализация события клика - PullRequest
0 голосов
/ 24 октября 2019

У меня возникают проблемы, когда я пытаюсь реализовать наблюдаемое нажатие на функцию, которую я уже реализовал. Примеры, которые я видел до сих пор, реализованы с использованием fromEvent или Subject следующим образом:

import {Subject} from "rxjs/Subject";

export class Component {

    private clickStream$ = new Subject<Event>();

    @Output() observable$ = this.clickStream.asObservable();

    buttonClick(event:Event) {
        this.clickStream$.next(event);
    }
}

их html

<button type="button" (click)="buttonClick($event)">click me</button>

Теперь рассмотрим мою реализацию ниже.

component.ts

export class MyComponent {
  result;
  public search(queryString: string) {
    this.myService.search().subscribe((res) => result = res )
  }
}

index.html

<form [formGroup]="searchForm">
    <input
      formControlName="queryString"
      placeholder="Enter keyword"
      type="text"
      (keyup.enter)="search(searchForm.value.queryString)"
     >
     <div (click)="search(searchForm.value.queryString)"></div> <!-- added an icon with css ->
</form>

service.ts

export class SearchService {
constructor(private http: HttpClient) {}

  search(queryString: string) {
    if (!queryString) {
      return;
    }
    return this.http.get(`${this.BASE_URL}&q=${queryString}`);
  }

}

Моя проблема в том, как использовать мой текущий search()и все еще иметь возможность подписаться на мой метод myService.search(), используя найденный мной подход. (т.е. пример кода в этом посте) Я понимаю (я думаю) потоки и концепцию Observables, но все же это пинает меня в задницу.

Заранее спасибо за любую помощь.

1 Ответ

1 голос
/ 24 октября 2019

Есть некоторые фундаментальные проблемы с вашим кодом.

1) Существует несколько опечаток, а именно такие методы, как ваш метод обслуживания (search или searchMedPolicies?)

2) Вы не импортировали и не инициализировали formGroupвнутри вашего компонента.

3) То, как вы обрабатываете свои подписки в своем компоненте - нет необходимости добавлять инструкцию возврата в вашу подписку.

Что касается события вашей подписки, вы можете простопередать событие click вашему субъекту , используя next().

Затем вы подписываетесь на свой clickStream$ субъект и делаете необходимые HTTP-запросы.

Вот моирекомендуемые исправления.

<form [formGroup]="searchForm">
  <input
    formControlName="queryString"
    placeholder="Enter keyword"
    type="text"
    (keyup.enter)="onSearch()"
   >
   <div (click)="onSearch($event)"></div> 
</form>

И на ваших component.ts,

import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { Subject } from 'rxjs';
import { switchMap } from 'rxjs/operators';

// other imports 

@Component({
  // etc etc
})

export class YourComponent implements OnInit {
  clickStream$ = new Subject<Event>();

  searchForm = this.fb.group({
    queryString: '',
  })

  constructor(
    private fb: FormBuilder, 
    private myService: SearchService,
  ) { }

  ngOnInit() {
    this.clickStream$
      .pipe(
        switchMap((event) => {            
          const { queryString } = this.searchForm.value;
          // console.log(event);
          // console.log(queryString);

          return this.myService.search(queryString)
        }),
      ).subscribe(response => {
        console.log(response);
        // do the rest
      });
  }

  onSearch() {
    this.clickStream$.next(event);
  }
}

И на вашем service.ts убедитесь, что имена методов тоже совпадают.

export class SearchService {

  constructor(private http: HttpClient) {}

  search(queryString: string) {
    if (!queryString) {
      return;
    }
    return this.http.get(`${this.BASE_URL}&q=${queryString}`);
  }

}
...