angular - Angular 6,根据所选值从 GET http 调用中获取过滤后的数据,无需管道
问题描述
我正在使用分别构建的 Angular 6 和 ASP.NET Core 2.0。我有一个 HTTP GET 调用,它将位置列表返回到下拉列表。我想过滤 TeacherName 选项/下拉列表以仅显示与下拉列表中选择的位置相同的名称(在后端 SQL 数据库中)。浏览器中的错误说... TypeError: Cannot read property 'filter' of undefined
所以,我认为“filterTeachers”函数中的语法不正确,但它可能是别的东西(?)。Angular 可以在没有管道的情况下进行这些类型的客户端过滤吗?它应该作为 linq 查询而不是在后端完成吗?
这里是 update.component.html...
<div>
<form>
<div class="form-group">
<label for="LogLocation-input">Select Your Location </label>
<select type="text" id="LogLocation" name="LogLocation-input" [(ngModel)]="teacherLocInput" (ngModelChange)="basedOnLoc($event)" class="form-control">
<option *ngFor="let loc of teacherLocationsData" [value]="loc.location">
{{ loc.location }}
</option>
</select>
</div>
<div class="form-group">
<label for="TeacherName-input">Enter Teacher Name </label>
<select type="text" id="TeacherName" name="TeacherName-input" [(ngModel)]="loggingInfo.ClassTimesTeacherName" class="form-control">
<option *ngFor="let nam of filteredTeacherNames">
{{ nam.name }}
</option>
</select>
</div>
<button type="button" class="btn btn-primary" (click)="addOrUpdateLoggingRecord($event);">Save</button>
<h2 *ngIf="!loggingInfo || loggingInfo.id === undefined">Add record</h2>
<h2 *ngIf="loggingInfo && loggingInfo.id !== undefined">Update record (ID: )</h2>
</form>
</div>
这是 update.component.ts...
import { Component, EventEmitter, Input, Output, OnInit } from '@angular/core';
import { TimeService } from '../time.service';
@Component({
selector: 'app-update',
templateUrl: './update.component.html',
styleUrls: ['./update.component.css']
})
export class UpdateComponent implements OnInit {
@Output() loggingCreated = new EventEmitter<any>();
@Input() loggingInfo: any;
public buttonText = 'Save';
public teacherLocationsData: Array<any>;
public teacherNameData: Array<any>;
public filteredTeacherNames: Array<any>;
private _teacherLocInput: string;
get teacherLocInput(): string {
return this._teacherLocInput;
}
set teacherLocInput(value: string) {
this._teacherLocInput = value;
this.filteredTeacherNames = this.filterTeachers(value);
}
filterTeachers(teacherLocInput: string) {
return this.teacherNameData.filter(teacher => teacher.location === this.teacherLocInput);
}
constructor(private timeService: TimeService) {
this.clearAllInfo();
timeService.getTeacherLocation().subscribe((importLocations: any) => this.teacherLocationsData = importLocations);
}
ngOnInit() {
// not sure if needed
this.teacherNameData;
}
basedOnLoc(val:any) {
// not sure if this is calling API
this.customFunction(val);
}
// gets called on the change event of location selected
customFunction(val:any) {
this.teacherLocInput = val;
this.timeService.getTeacherName().subscribe((importTeacherName: any) => this.teacherNameData = importTeacherName);
}
private clearAllInfo = function() {
// Create an empty logging object
this.loggingInfo = {
id: undefined,
date: '',
ClassTimesStudentID: '',
ClassTimesStudentName:'',
ClassTimesSubjects: '',
ClassTimesLogLocation: '',
ClassTimesTeacherID: '',
ClassTimesTeacherName: '',
ClassTimesLogOff: '',
timeInSeconds: 0,
distanceInMeters: 0
};
};
public addOrUpdateLoggingRecord = function(event) {
this.loggingCreated.emit(this.loggingInfo);
this.clearAllInfo();
console.log(this.LoggingIfo);
};
}
这是使用 Angular Reactive Forms 的新版本...
import { Component, EventEmitter, Input, Output, OnInit } from '@angular/core';
import { TimeService } from '../time.service';
import { FormGroup, FormBuilder, FormControl } from '@angular/forms';
@Component({
selector: 'app-update',
templateUrl: './update.component.html',
styleUrls: ['./update.component.css']
})
export class UpdateComponent implements OnInit {
timeLogForm: FormGroup;
@Output() loggingCreated = new EventEmitter<any>();
@Input() loggingInfo: any;
public buttonText = 'Save';
public teacherLocationsData: Array<any>;
public teacherNameData: Array<any>;
public filteredTeacherNames: Array<any>;
get filterTeachers() {
return this.teacherNameData.filter(teacher => teacher.location === this.timeLogForm.controls.location.value);
}
constructor(private timeService: TimeService, private fb: FormBuilder) {
timeService.getTeacherLocation().subscribe((importLocations: any) => this.teacherLocationsData = importLocations);
timeService.getTeacherName().subscribe((importTeacherName: any) => this.teacherNameData = importTeacherName);
}
ngOnInit() {
this.buildForm();
}
buildForm() {
this.timeLogForm = this.fb.group({
id: null,
ClassTimesLogLocation: null,
ClassTimesTeacherName: null,
});
}
public addOrUpdateLoggingRecord = function(event) {
this.loggingCreated.emit(this.loggingInfo);
};
}
这是反应式表单模板...
<div>
<form [formGroup]="timeLogForm">
div class="form-group">
<label for="LogLocation-input">Select Your Location </label>
<select type="text" id="LogLocation" name="LogLocation-input" formGroupName="ClassTimesLogLocation" class="form-control">
<option *ngFor="let loc of teacherLocationsData" [value]="loc.location">
{{ loc.location }}
</option>
</select>
</div>
<div class="form-group">
<label for="TeacherName-input">Enter Teacher Name </label>
<select type="text" id="TeacherName" name="TeacherName-input" formGroupName="ClassTimesTeacherName" class="form-control">
<option *ngFor="let nam of filteredTeacherNames" [value]="nam.name" >
{{ nam.name }}
</option>
</select>
</div> <button type="button" class="btn btn-primary" (click)="addOrUpdateLoggingRecord($event);">Save</button>
<h2 *ngIf="!loggingInfo || loggingInfo.id === undefined">Add record</h2>
<h2 *ngIf="loggingInfo && loggingInfo.id !== undefined">Update record (id: )</h2>
</form>
</div>
解决方案
首先,您正在进行的许多逻辑都可以使用 Angular 的 ReactiveForms 来简化。https://angular.io/guide/reactive-forms老实说,这是我最喜欢的 Angular 部分之一。它使类成为表单而不是模板的唯一真实来源。无论如何,关于你的问题。您可以使用 getter 作为数组来迭代*ngFor
. 它将在更改时运行该方法,以便为您处理它。
在您的 .ts 文件中:
get filterTeachers() {
return this.teacherNameData.filter(teacher => teacher.location === this.teacherLocInput);
}
html:
<option *ngFor="let nam of filterTeachers">
{{ nam.name }}
</option>
如果您对 ReactiveForms 感兴趣:
component.ts (当然缺少很多你已经拥有的数据):
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';
@Component({
selector: 'selector-name',
styleUrls: ['selector-name.component.scss'],
template: `something.html `
})
export class SomeComponent implements OnInit {
teacherLocationForm: FormGroup;
get filterTeachers() {
return this.teacherNameData.filter(teacher => teacher.location === this.teacherLocationForm.controls.location.value);
}
constructor (private fb: FormBuilder) {}
ngOnInit() {
this.buildForm();
}
buildForm() {
this.teacherLocationForm = this.fb.group({
location: null,
teacher: null
});
}
}
HTML:
<div>
<form [formGroup]="teacherLocationForm">
<div class="form-group">
<label for="LogLocation-input">Select Your Location </label>
<select type="text" id="LogLocation" name="LogLocation-input" formGroupName="location" class="form-control">
<option *ngFor="let loc of teacherLocationsData" [value]="loc.location">
{{ loc.location }}
</option>
</select>
</div>
<div class="form-group">
<label for="TeacherName-input">Enter Teacher Name </label>
<select type="text" id="TeacherName" name="TeacherName-input" formGroupName="teacher" class="form-control">
<option *ngFor="let nam of filterTeachers">
{{ nam.name }}
</option>
</select>
</div>
<button type="button" class="btn btn-primary" (click)="addOrUpdateLoggingRecord($event);">Save</button>
<h2 *ngIf="!loggingInfo || loggingInfo.id === undefined">Add record</h2>
<h2 *ngIf="loggingInfo && loggingInfo.id !== undefined">Update record (ID: )</h2>
</form>
然后您的值将更新到该teacherLocationForm
属性中。您可以使用 访问它们this.teacherLocationForm.value
。表单组非常强大,可以保存表单的状态、错误,并且很容易提交。
推荐阅读
- list - Python 3 OOP - 如何从属性列表(对象实例)中按首字母获取名称
- asp.net-mvc - Kendo Control 仅从主页调用 Controller 的操作方法。它不会从另一个页面调用它
- android - NotificationChannel 设置声音和振动不起作用
- c# - 如何实现连接平面文件中的记录?
- excel - 如何应用条件格式来显示一个字段是强制填写的基于对另一个工作表的 vlookup
- javascript - 在 Javascript 中,值 0/0 返回 NaN。但是为什么 typeof 运算符会将此值作为 Number 类型返回呢?
- python - 如何从python中的字符串中拆分一个字母
- laravel - 为每个 URL 路由单独的 Laravel 控制器?
- r - 更改基于 x 变量的箱线图背景 (ggplot2)
- javascript - 无法通过输入文件绘制导入的图像