问题
I'm having trouble wrapping my head around implementing an Observable clicking event to a function I already implemented. The examples I have seen so far are implemented using the fromEvent
or Subject
like so;
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);
}
}
their html
<button type="button" (click)="buttonClick($event)">click me</button>
Now consider my implementation below.
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}`);
}
}
My trouble is how to use my current search()
and still be able to subscribe to my myService.search()
method while using the approach I found. (i.e. the example code in this post)
I understand ( I think ) streams, and the concept of Observables, but yet this is kicking my butt.
thanks in advance for any help.
回答1:
There are some fundemental issues with your code.
1) There are a few typos, namely the methods such as your service method (search
or searchMedPolicies
?)
2) You did not import and initialise your formGroup
within your component.
3) The way you handle your subscriptions on your component - there is no need to add the return statement on your subscription.
As for your subscription event, you can simply feed the click event to your Subject using next()
.
Then, you subscribe to your clickStream$
Subject and make the necessary HTTP requests.
Here are my recommended corrections.
<form [formGroup]="searchForm">
<input
formControlName="queryString"
placeholder="Enter keyword"
type="text"
(keyup.enter)="onSearch()"
>
<div (click)="onSearch($event)"></div>
</form>
And on your 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);
}
}
And on your service.ts, make sure the method names are matching too.
export class SearchService {
constructor(private http: HttpClient) {}
search(queryString: string) {
if (!queryString) {
return;
}
return this.http.get(`${this.BASE_URL}&q=${queryString}`);
}
}
来源:https://stackoverflow.com/questions/58543296/angular-rxjs-observable-clicking-event-implementation