如何检索 EventEmitter 响应 Angular 6
How to retrieve EventEmitter response Angular 6
我有以下父组件:
<h1>Vehicle Inventory</h1>
<p *ngIf="!vehicles"><em>No vehicle entries found</em></p>
<div *ngIf="vehicles">
<ul class="nav nav-pills nav-fill">
<li class="nav-item">
<a class="nav-link" routerLink="/home/price" routerLinkActive="active">Search By price</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/home/make-model" routerLinkActive="active">Search By Make Or Model</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/home/engine-capacity" routerLinkActive="active">Search By Engine Capacity</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/home/cylinder-variant" routerLinkActive="active">Search By Cylinder Variant</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/home/cylinder-capacity" routerLinkActive="active">Search By Cylinder Capacity</a>
</li>
</ul>
<router-outlet></router-outlet>
</div>
<table class="table" *ngIf="vehicles">
<thead class="thead-dark">
<tr>
<th scope="col">Make</th>
<th scope="col">Model</th>
<th scope="col">Engine Capacity</th>
<th scope="col">Cylinder Variant</th>
<th scope="col">Top Speed</th>
<th scope="col">Price (R)</th>
<th scope="col">Cylinder Capacity</th>
<th scope="col">Air Pressure/second</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let vehicle of vehicles">
<td>{{ vehicle.Make }}</td>
<td>{{ vehicle.Model }}</td>
<td>{{ vehicle.EngineCapacity }}</td>
<td>{{ vehicle.CylinderVariant }}</td>
<td>{{ vehicle.TopSpeed }}</td>
<td>{{ vehicle.Price }}</td>
<td>{{ vehicle.IndividualCylinderCapacity }}</td>
<td>{{ vehicle.AirPressurePerSecond }}</td>
</tr>
</tbody>
</table>
从上面可以看出,我在这里进行了一些导航,这些导航将确定要加载到 <router-outlet>
中的子组件。
我的子组件通过 EventEmitter
发出一个事件,如下所示:
import { Component, OnInit, Input, Output } from '@angular/core';
import { VehicleService } from '../../Services/VehicleService';
import { EventEmitter } from '@angular/core';
import { Vehicle } from '../../Models/Vehicle';
@Component({
selector: 'app-search-cylinder-capacity',
templateUrl: './search-cylinder-capacity.component.html',
styleUrls: ['./search-cylinder-capacity.component.css']
})
export class SearchCylinderCapacityComponent implements OnInit {
@Input() cylinderCapacity: any;
@Output() dataNotifier: EventEmitter<Vehicle[]> = new EventEmitter();
constructor(private service: VehicleService) { }
ngOnInit() {
}
searchVehicle() {
this.service
.SearchVehiclesByCylinderCapacity(this.cylinderCapacity)
.subscribe(response => this.dataNotifier.emit(response));
}
}
如何捕获此事件的响应,以便我的父组件的车辆:Vehicle[]
可以填充事件的响应?
无法监听来自 router-outlet
的事件,因为它只是一个占位符。您可以使用 "shared service",如以下答案所述:。
为了模仿 dateNotifier
事件,共享服务可能如下所示:
@Injectable()
export class DateNotifierService {
private source = new Subject<Vehicle[]>();
public event$ = this.source.asObservable();
emit(eventData: Vehicle[]): void {
this.source.next(eventData);
}
}
然后您可以将它注入您的子组件并发出事件:
export class SearchCylinderCapacityComponent {
vehicles: Vehicle[];
constructor(private dateNotifier: DateNotifierService) {}
onClick(){
this.dateNotifier.emit(this.vehicles);
}
}
以及将其注入到您的父组件中并捕获事件:
export class ParentComponent {
constructor(private dateNotifier: DateNotifierService) {
dateNotifier.event$.subscribe(vehicles => console.log(vehicles));
}
}
根据@vincecampanale 提到的内容,这就是我想出的:
在我的 VehicleService
class 中,我有以下代码用于根据不同的搜索检索车辆。 VehicleService class 还包括一个 dataChangedEvent: EventEmitter<Vehicle[]>
,当发送到该服务时,将保存 Vehicle 的最新结果。
这是我的 VehicleService
import { Injectable, ErrorHandler, EventEmitter } from "@angular/core";
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
import { ConfigService } from "./ConfigService";
import { Vehicle } from "../Models/Vehicle";
import { HttpClient } from "@angular/common/http";
import { HttpResponse } from "selenium-webdriver/http";
@Injectable({
providedIn: "root"
})
export class VehicleService {
dataChangedEvent: EventEmitter<Vehicle[]> = new EventEmitter();
constructor(private http: HttpClient, private configService: ConfigService){
}
SearchVehiclesByCylinderCapacity(cylinderCapacity: any): Observable<Vehicle[]> {
var finalEndPoint = this.configService.SearchVehiclesByCylinderCapacityEndpoint + cylinderCapacity;
return this.makeRequest(finalEndPoint);
}
SearchTop10ByAirPressure(airPressure: any): Observable<Vehicle[]> {
var finalEndPoint = this.configService.SearchVehiclesByAirPressureEndpoint + airPressure;
return this.makeRequest(finalEndPoint);
}
private makeRequest(endpoint: string): Observable<Vehicle[]> {
return this.http.get<Vehicle[]>(endpoint);
}
}
每个子组件,一旦在 subscribe()
处理程序中收到响应,就会将数据发送到 K 中的 dataChangedEvent
。
这是一个子组件:
import { Component, OnInit } from '@angular/core';
import { VehicleService } from '../../Services/VehicleService';
@Component({
selector: 'app-search-engine-capacity',
templateUrl: './search-engine-capacity.component.html',
styleUrls: ['./search-engine-capacity.component.css']
})
export class SearchEngineCapacityComponent implements OnInit {
engineCapacity: any;
constructor(private vehicleService: VehicleService) {
}
ngOnInit() {
}
searchVehicle(): void {
this.vehicleService
.SearchVehiclesByEngineCapacity(this.engineCapacity)
.subscribe(response => this.vehicleService.dataChangedEvent.emit(response));
}
}
最后,在父组件中,我subscribe()
到VehicleService
中的dataChangedEvent
,当搜索到的车辆数据发生变化时,会通知父组件。
下面是我的父组件,它从 constructor
中覆盖 VehicleService
中的 dataChangedEvent
import { Component, OnInit, Input } from '@angular/core';
import { VehicleService } from '../../Services/VehicleService';
import { Vehicle } from '../../Models/Vehicle';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
vehicles: Vehicle[];
constructor(private vehicleService: VehicleService) {
this.vehicleService.dataChangedEvent.subscribe(response => this.vehicles = response)
}
ngOnInit() {
this.vehicleService
.GetAllVehicles()
.subscribe(response => this.vehicles = response,
error => console.log(error));
}
populateGrid(vehicleData: Vehicle[]){
this.vehicles = vehicleData;
}
}
此答案基于 monstertjie_za 自己对问题的回答。
鉴于 VehicleService
似乎提供了获取一系列车辆的不同方法。我会公开 vehicles
本身。
@Injectable({
providedIn: "root"
})
export class VehicleService {
vehicles: Vehicle[] | undefined;
constructor(private http: HttpClient, private configService: ConfigService) { }
searchVehiclesByCylinderCapacity(cylinderCapacity: any): void {
var finalEndPoint = this.configService.SearchVehiclesByCylinderCapacityEndpoint
+ cylinderCapacity;
this.makeRequest(finalEndPoint);
}
searchTop10ByAirPressure(airPressure: any): void {
var finalEndPoint = this.configService.SearchVehiclesByAirPressureEndpoint
+ airPressure;
this.makeRequest(finalEndPoint);
}
private makeRequest(endpoint: string): void {
this.http.get<Vehicle[]>(endpoint)
.subscribe(vehicles => this.vehicles = vehicles);
}
}
然后子组件只启动调用但实际上不做任何其他事情:
@Component({
selector: 'app-search-engine-capacity'
})
export class SearchEngineCapacityComponent {
constructor(private vehicleService: VehicleService) { }
searchVehicle(): void {
this.vehicleService.searchVehiclesByEngineCapacity(this.engineCapacity);
}
}
而您的 HomeComponent
只是公开了服务,该服务公开了您认为要使用的车辆:
@Component({
selector: 'app-home',
})
export class HomeComponent implements OnInit {
constructor(vehicleService: VehicleService) {}
ngOnInit() {
this.vehicleService.getAllVehicles();
}
}
<table class="table" *ngIf="vehicleService.vehicles">
<thead class="thead-dark">
<tr>
<th scope="col">Make</th>
<th scope="col">Model</th>
<th scope="col">Engine Capacity</th>
<th scope="col">Cylinder Variant</th>
<th scope="col">Top Speed</th>
<th scope="col">Price (R)</th>
<th scope="col">Cylinder Capacity</th>
<th scope="col">Air Pressure/second</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let vehicle of vehicleService.vehicles">
<td>{{ vehicle.Make }}</td>
<td>{{ vehicle.Model }}</td>
<td>{{ vehicle.EngineCapacity }}</td>
<td>{{ vehicle.CylinderVariant }}</td>
<td>{{ vehicle.TopSpeed }}</td>
<td>{{ vehicle.Price }}</td>
<td>{{ vehicle.IndividualCylinderCapacity }}</td>
<td>{{ vehicle.AirPressurePerSecond }}</td>
</tr>
</tbody>
</table>
我有以下父组件:
<h1>Vehicle Inventory</h1>
<p *ngIf="!vehicles"><em>No vehicle entries found</em></p>
<div *ngIf="vehicles">
<ul class="nav nav-pills nav-fill">
<li class="nav-item">
<a class="nav-link" routerLink="/home/price" routerLinkActive="active">Search By price</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/home/make-model" routerLinkActive="active">Search By Make Or Model</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/home/engine-capacity" routerLinkActive="active">Search By Engine Capacity</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/home/cylinder-variant" routerLinkActive="active">Search By Cylinder Variant</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/home/cylinder-capacity" routerLinkActive="active">Search By Cylinder Capacity</a>
</li>
</ul>
<router-outlet></router-outlet>
</div>
<table class="table" *ngIf="vehicles">
<thead class="thead-dark">
<tr>
<th scope="col">Make</th>
<th scope="col">Model</th>
<th scope="col">Engine Capacity</th>
<th scope="col">Cylinder Variant</th>
<th scope="col">Top Speed</th>
<th scope="col">Price (R)</th>
<th scope="col">Cylinder Capacity</th>
<th scope="col">Air Pressure/second</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let vehicle of vehicles">
<td>{{ vehicle.Make }}</td>
<td>{{ vehicle.Model }}</td>
<td>{{ vehicle.EngineCapacity }}</td>
<td>{{ vehicle.CylinderVariant }}</td>
<td>{{ vehicle.TopSpeed }}</td>
<td>{{ vehicle.Price }}</td>
<td>{{ vehicle.IndividualCylinderCapacity }}</td>
<td>{{ vehicle.AirPressurePerSecond }}</td>
</tr>
</tbody>
</table>
从上面可以看出,我在这里进行了一些导航,这些导航将确定要加载到 <router-outlet>
中的子组件。
我的子组件通过 EventEmitter
发出一个事件,如下所示:
import { Component, OnInit, Input, Output } from '@angular/core';
import { VehicleService } from '../../Services/VehicleService';
import { EventEmitter } from '@angular/core';
import { Vehicle } from '../../Models/Vehicle';
@Component({
selector: 'app-search-cylinder-capacity',
templateUrl: './search-cylinder-capacity.component.html',
styleUrls: ['./search-cylinder-capacity.component.css']
})
export class SearchCylinderCapacityComponent implements OnInit {
@Input() cylinderCapacity: any;
@Output() dataNotifier: EventEmitter<Vehicle[]> = new EventEmitter();
constructor(private service: VehicleService) { }
ngOnInit() {
}
searchVehicle() {
this.service
.SearchVehiclesByCylinderCapacity(this.cylinderCapacity)
.subscribe(response => this.dataNotifier.emit(response));
}
}
如何捕获此事件的响应,以便我的父组件的车辆:Vehicle[]
可以填充事件的响应?
无法监听来自 router-outlet
的事件,因为它只是一个占位符。您可以使用 "shared service",如以下答案所述:
为了模仿 dateNotifier
事件,共享服务可能如下所示:
@Injectable()
export class DateNotifierService {
private source = new Subject<Vehicle[]>();
public event$ = this.source.asObservable();
emit(eventData: Vehicle[]): void {
this.source.next(eventData);
}
}
然后您可以将它注入您的子组件并发出事件:
export class SearchCylinderCapacityComponent {
vehicles: Vehicle[];
constructor(private dateNotifier: DateNotifierService) {}
onClick(){
this.dateNotifier.emit(this.vehicles);
}
}
以及将其注入到您的父组件中并捕获事件:
export class ParentComponent {
constructor(private dateNotifier: DateNotifierService) {
dateNotifier.event$.subscribe(vehicles => console.log(vehicles));
}
}
根据@vincecampanale 提到的内容,这就是我想出的:
在我的 VehicleService
class 中,我有以下代码用于根据不同的搜索检索车辆。 VehicleService class 还包括一个 dataChangedEvent: EventEmitter<Vehicle[]>
,当发送到该服务时,将保存 Vehicle 的最新结果。
这是我的 VehicleService
import { Injectable, ErrorHandler, EventEmitter } from "@angular/core";
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
import { ConfigService } from "./ConfigService";
import { Vehicle } from "../Models/Vehicle";
import { HttpClient } from "@angular/common/http";
import { HttpResponse } from "selenium-webdriver/http";
@Injectable({
providedIn: "root"
})
export class VehicleService {
dataChangedEvent: EventEmitter<Vehicle[]> = new EventEmitter();
constructor(private http: HttpClient, private configService: ConfigService){
}
SearchVehiclesByCylinderCapacity(cylinderCapacity: any): Observable<Vehicle[]> {
var finalEndPoint = this.configService.SearchVehiclesByCylinderCapacityEndpoint + cylinderCapacity;
return this.makeRequest(finalEndPoint);
}
SearchTop10ByAirPressure(airPressure: any): Observable<Vehicle[]> {
var finalEndPoint = this.configService.SearchVehiclesByAirPressureEndpoint + airPressure;
return this.makeRequest(finalEndPoint);
}
private makeRequest(endpoint: string): Observable<Vehicle[]> {
return this.http.get<Vehicle[]>(endpoint);
}
}
每个子组件,一旦在 subscribe()
处理程序中收到响应,就会将数据发送到 K 中的 dataChangedEvent
。
这是一个子组件:
import { Component, OnInit } from '@angular/core';
import { VehicleService } from '../../Services/VehicleService';
@Component({
selector: 'app-search-engine-capacity',
templateUrl: './search-engine-capacity.component.html',
styleUrls: ['./search-engine-capacity.component.css']
})
export class SearchEngineCapacityComponent implements OnInit {
engineCapacity: any;
constructor(private vehicleService: VehicleService) {
}
ngOnInit() {
}
searchVehicle(): void {
this.vehicleService
.SearchVehiclesByEngineCapacity(this.engineCapacity)
.subscribe(response => this.vehicleService.dataChangedEvent.emit(response));
}
}
最后,在父组件中,我subscribe()
到VehicleService
中的dataChangedEvent
,当搜索到的车辆数据发生变化时,会通知父组件。
下面是我的父组件,它从 constructor
VehicleService
中的 dataChangedEvent
import { Component, OnInit, Input } from '@angular/core';
import { VehicleService } from '../../Services/VehicleService';
import { Vehicle } from '../../Models/Vehicle';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
vehicles: Vehicle[];
constructor(private vehicleService: VehicleService) {
this.vehicleService.dataChangedEvent.subscribe(response => this.vehicles = response)
}
ngOnInit() {
this.vehicleService
.GetAllVehicles()
.subscribe(response => this.vehicles = response,
error => console.log(error));
}
populateGrid(vehicleData: Vehicle[]){
this.vehicles = vehicleData;
}
}
此答案基于 monstertjie_za 自己对问题的回答。
鉴于 VehicleService
似乎提供了获取一系列车辆的不同方法。我会公开 vehicles
本身。
@Injectable({
providedIn: "root"
})
export class VehicleService {
vehicles: Vehicle[] | undefined;
constructor(private http: HttpClient, private configService: ConfigService) { }
searchVehiclesByCylinderCapacity(cylinderCapacity: any): void {
var finalEndPoint = this.configService.SearchVehiclesByCylinderCapacityEndpoint
+ cylinderCapacity;
this.makeRequest(finalEndPoint);
}
searchTop10ByAirPressure(airPressure: any): void {
var finalEndPoint = this.configService.SearchVehiclesByAirPressureEndpoint
+ airPressure;
this.makeRequest(finalEndPoint);
}
private makeRequest(endpoint: string): void {
this.http.get<Vehicle[]>(endpoint)
.subscribe(vehicles => this.vehicles = vehicles);
}
}
然后子组件只启动调用但实际上不做任何其他事情:
@Component({
selector: 'app-search-engine-capacity'
})
export class SearchEngineCapacityComponent {
constructor(private vehicleService: VehicleService) { }
searchVehicle(): void {
this.vehicleService.searchVehiclesByEngineCapacity(this.engineCapacity);
}
}
而您的 HomeComponent
只是公开了服务,该服务公开了您认为要使用的车辆:
@Component({
selector: 'app-home',
})
export class HomeComponent implements OnInit {
constructor(vehicleService: VehicleService) {}
ngOnInit() {
this.vehicleService.getAllVehicles();
}
}
<table class="table" *ngIf="vehicleService.vehicles">
<thead class="thead-dark">
<tr>
<th scope="col">Make</th>
<th scope="col">Model</th>
<th scope="col">Engine Capacity</th>
<th scope="col">Cylinder Variant</th>
<th scope="col">Top Speed</th>
<th scope="col">Price (R)</th>
<th scope="col">Cylinder Capacity</th>
<th scope="col">Air Pressure/second</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let vehicle of vehicleService.vehicles">
<td>{{ vehicle.Make }}</td>
<td>{{ vehicle.Model }}</td>
<td>{{ vehicle.EngineCapacity }}</td>
<td>{{ vehicle.CylinderVariant }}</td>
<td>{{ vehicle.TopSpeed }}</td>
<td>{{ vehicle.Price }}</td>
<td>{{ vehicle.IndividualCylinderCapacity }}</td>
<td>{{ vehicle.AirPressurePerSecond }}</td>
</tr>
</tbody>
</table>