[英]Angular 7 - Search bar and results in different views
我创建了两个组件:
search-bar.component.ts
:显示在所有视图中search.component.ts
:应显示结果(来自 REST API 的响应)工作是这样的:在应用程序的任何地方,我都想执行全局搜索(产品、用户、事件等...)。 我在搜索栏中写了一些东西,点击搜索,然后我被重定向到结果页面。 结果是从 REST API 获取的。
PS:我在互联网上搜索了几个小时,但没有找到..奇怪! 我确实阅读了很多关于@Input
和@Output
。
我接近实现我想要的,用这种代码:
import { Component, OnInit } from '@angular/core';
import {Router} from '@angular/router';
@Component({
selector: 'app-search-bar',
templateUrl: './search-bar.component.html',
styleUrls: ['./search-bar.component.css']
})
export class SearchBarComponent implements OnInit {
constructor(
private router: Router
) { }
ngOnInit() {
}
onSubmit(search: string, from: string, to: string) {
this.router.navigate(['recherche'], {
queryParams: {
search: search,
from: from,
to: to
}
});
}
}
表单是这样构建的: <form ngNoForm class="form-inline">
和魔法(click)="onSubmit(search.value, from.value, to.value);"
.
但我不认为这是做这类事情的最佳方式。 (这是我的第一个问题)
此外,当我在结果视图中时,如果我再次在搜索栏上进行搜索,它会像基本href
一样完全重新加载应用程序。 (这是我的第二个问题)
我没有找到很多用例或示例来满足我的需求,但它似乎非常基本。
编辑 1:两个组件的代码
search-bar.component.html
代码:
<div class="event-background-blue margin-20-top">
<div class="container">
<!-- Search -->
<div class="row">
<div class="col-12">
<form ngNoForm class="form-inline">
<div class="row">
<div class="col">
<input #search id="search" name="search" class="form-control form-control-lg" type="text" />
</div>
<div class="col">
<div class="input-group date datepicker" data-provide="datepicker" data-date-format="dd/mm/yyyy" data-date-week-start="1" data-date-language="fr">
<input placeholder="Du" type="text" class="form-control form-control-lg" #from name="from" autocomplete="off" >
<div class="input-group-append">
<span class="input-group-text" id="basic-addon2"><i class="fa fa-calendar" aria-hidden="true"></i></span>
</div>
</div>
</div>
<div class="col">
<div class="input-group date datepicker" data-provide="datepicker" data-date-format="dd/mm/yyyy" data-date-week-start="1" data-date-language="fr">
<input placeholder="Au" type="text" class="form-control form-control-lg" #to name="to" autocomplete="off" >
<div class="input-group-append">
<span class="input-group-text" id="basic-addon2"><i class="fa fa-calendar" aria-hidden="true"></i></span>
</div>
</div>
</div>
<div class="col">
<button (click)="onSubmit(search.value, from.value, to.value);" class="btn btn-black" type="submit"><i class="fa fa-search"></i></button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
search.component.html
代码:
<app-search-bar></app-search-bar>
<div class="container">
<!-- Header -->
<div class="row">
<div class="col-12">
<h1 class="title-search text-primary">Search</h1>
</div>
</div>
<!-- Count of Events -->
<div class="row">
<div class="col-12 margin-20-bottom">
<h3>Events</h3>
</div>
<app-event class="col-12 col-md-6 col-lg-4 mb-10" *ngFor="let event of events" [event]="event"></app-event>
<div class="col-12" *ngIf="!events">
<p>No event, go to <a routerLink="/evenements">events !</a></p>
</div>
</div>
</div>
编辑 2:添加 search.component.ts 的代码:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { EventService } from '../../../services/event.service';
import { Event, EventsResp, EventsSearch } from '../../../models/event';
import { LocationService } from '../../../services/location.service';
import { Location, LocationsResp, LocationsSearch } from '../../../models/location';
import * as moment from 'moment';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {
constructor(
private route: ActivatedRoute,
private eventService: EventService,
private locationService: LocationService,
) { }
perPage: number = 20;
page: number = 1;
error: Error;
locations: Location[];
events: Event[];
ngOnInit() {
// Retreive the parameters
const search = this.route.snapshot.queryParamMap.get('search');
const from = this.route.snapshot.queryParamMap.get('from');
const to = this.route.snapshot.queryParamMap.get('to');
this.listEvents(search, from, to);
this.listLocations(search, from, to);
}
// listEvents returns all the events
listEvents(search, from, to): void {
// Set the parameters
let parameters: EventsSearch = {
from: moment(from).toISOString(),
to: moment(to).toISOString(),
search: search,
page: this.page,
per_page: this.perPage,
sort: "",
_location_id: ""
};
// List the events
this.eventService.listEvents(parameters)
.subscribe((resp: EventsResp) => {
this.events = resp['events'];
});
}
// listLocations returns all the locations
listLocations(search, from, to): void {
// Set the parameters
let parameters: LocationsSearch = {
page: this.page,
is_city_guide: undefined,
per_page: this.perPage,
sort: "",
search: search
};
// List the locations
this.locationService.listLocations(parameters)
.subscribe((resp: LocationsResp) => {
this.locations = resp['locations'];
});
}
}
编辑 3 :例如,Google Drive 中的搜索栏就是一个完美的例子,它无处不在,结果显示在结果页面中。
编辑 4 :
您有两种方法可以执行此操作:
快速和基于事件的
在您的搜索栏组件中创建一个事件发射器,并在 onSubmit 函数中触发它,传递搜索值。
// Search Bar Component import { EventEmitter, Output } from '@angular/core'; @Component({ selector: 'app-search-bar', templateUrl: ['./search-bar.component.html'], styleUrls: ['./search-bar.component.scss'] }) export class SearchBarComponent implements OnInit { @Output() searchEvent = new EventEmitter(); // constructor onSubmit(searchValue: string, ...) { // your function this.searchEvent.emit(searchValue); } }
<!-- Search Component --> <app-search-bar (searchEvent)="fetchResults($event)"> </app-search-bar>
基于服务的方式
创建在您的父模块中提供的搜索服务,并导入它的两个组件。 在服务中,创建将执行 Http 请求并更新主题的搜索功能。 搜索栏组件将在提交时调用此函数。 然后创建一个 observable 并从搜索组件中监听它以获取结果。
// Your service searchResults = new BehaviorSubject<Array<Result>>(); // constructor onResults() { return this.searchResults.asObservable(); } search(value: string) { this.http.post(url, value).subscribe(results => this.searchResults.next(results); } // Search-Bar component onSubmit(value: string) { // code this.searchService.search(value); } // Search component ngOnInit() { this.searchService.onResults().subscribe(results => this.results = results)); }
只需要在这种情况下使用@input 和@output 在这里只需要使用@output 并从父组件传递数据
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.