В моем проекте Angular 7 у меня есть реактивная форма с блоками select
и *ngFor
. Значения ngFor фильтруются на основе выбранного значения из опций, а пользовательский канал заботится о фильтрации. Всякий раз, когда я выбираю значение из опций, я вижу только вывод "[object Object]"
. Я пробовал (ngModelChange)=fun()
, change
события. Они не работали.
Форма
<div class="container container-fluid">
<h3 style="text-align: center"> BCMC CyberSecurity Jobs</h3>
<form [formGroup]="jobsForm">
<div class="row" style="margin-top: 40px">
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
<label> Job Type:
<select class="custom-select" formControlName="jobTypeControl" (ngModelChange)="updateFilterValue($event)">
<option *ngFor="let jobType of jobTypeObservable" [value]="jobType"> {{jobType.name}}</option>
</select>
</label>
</div>
<div *ngIf="jobsDataAvailable()" class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
<div class="has-text-centered">
<pagination-controls (pageChange)="page = $event" class="my-pagination" directionLinks="true" maxSize="5"
nextLabel="" previousLabel=""></pagination-controls>
</div>
</div>
</div>
<div *ngIf="jobsDataAvailable()">
<div *ngFor="let job of (jobsObservable) | stringFilter: this.jobsForm.controls['jobTypeControl'].value | paginate: { itemsPerPage: 10, currentPage: page }" class="row" style="margin-top: 10px">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<div class="card">
<div class="card-body">
<h5 class="card-title">{{job.title}}</h5>
<h6 class="card-subtitle mb-2 text-muted">{{job.city}}, {{job.state}}</h6>
<p class="card-text">This text will be replaced by clearance value in future</p>
<a class="btn btn-primary" href="https://bcmcllc.applytojob.com/apply/{{job.board_code}}">View and Apply</a>
</div>
</div>
</div>
</div>
</div> <!-- End of ngIf-->
</form>
</div>
Пользовательский фильтр :
import {Pipe, PipeTransform} from "@angular/core";
@Pipe({
name: 'stringFilter'
})
export class StringFilterPipe implements PipeTransform
{
transform(value: string[], filterValue: any)
{
if (!filterValue || filterValue === '')
{
return value;
}
return value.filter(item => -1 < item.toLowerCase().indexOf(filterValue.toLowerCase()));
}
}
**JobsListComponent**
import {Component, OnChanges, OnInit, SimpleChanges} from '@angular/core';
import {JobsService} from './services/jobs.service';
import {SERVER_API_URL} from '../../app.constants';
import {Observable} from 'rxjs';
import {Job} from './model/job';
import {FormControl, FormGroup} from '@angular/forms';
import {JobType} from './model/job-type';
@Component({
selector: 'app-jobs-list',
templateUrl: './jobs-list.component.html',
styleUrls: ['./jobs-list.component.css']
})
export class JobsListComponent implements OnInit
{
jobsObservable: Observable<Job[]>;
jobTypeObservable: Observable<JobType[]>;
page: number = 1;
jobsForm = new FormGroup({
jobTypeControl: new FormControl({value: '', disabled: false})
});
//this.form.controls['jobTypeControl'].value
//jobsForm.get('jobTypeControl').value
constructor(private jobsService: JobsService) {
}
ngOnInit()
{
this.getAllJobTypes();
this.getAllJobs();
}
getAllJobs() {
let url = SERVER_API_URL + 'jobs/all';
this.jobsService.getAllJobs(url).subscribe(
data => {
// @ts-ignore
this.jobsObservable = data;
},
error => console.error('Failed to retrieve values from backend, error=> ' + error),
() => console.log('Jobs retrieved from backend'));
return this.jobsObservable;
}
getAllJobTypes() {
let url = SERVER_API_URL + 'jobtypes/all';
this.jobsService.getAllJobTypes(url).subscribe(
data => {
// @ts-ignore
this.jobTypeObservable = data;
},
error => console.error('Failed to retrieve values from backend, error=> ' + error),
() => console.log('Job Types retrieved from backend'));
return this.jobTypeObservable;
}
jobsDataAvailable() {
return this.jobsObservable !== undefined;
}
updateFilterValue(event)
{
console.log("Emitted Value "+event);
}
}