- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个巨大的县
列表,并且想要实现自动完成功能。我使用相同的表单来添加
新客户或更新
现有客户。
现在,问题是,为了添加新客户,我的程序运行得很好,但是当我更新它时,在县下拉列表中它显示 countyId
而不是 name
。如何实现这一目标?按顺序查看图片
县架构如下
{
countyId: number;
name:string
}
我正在尝试在 html 中使用以下代码
<mat-form-field appearance="outline" fxFlex="50" class="pr-4">
<mat-label>County</mat-label>
<input type="text" placeholder="County" name="" matInput formControlName="countyId" [matAutocomplete]="auto">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option *ngFor="let county of filteredCounties | async" [value]="county.name">
{{county.name}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
在我的组件文件中
import { Component, OnInit, Inject, ViewChild, AfterViewInit, ElementRef, ComponentRef } from '@angular/core';
import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';
import { Router, ActivatedRoute } from '@angular/router';
import { CustomerService } from '../../../../services/customer/customer.service';
import { CountyService } from '../../../../services/county/county.service';
import { SubCountyService } from '../../../../services/subCounty/sub-county.service';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import PNotify from 'pnotify/dist/es/PNotify';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
@Component({
selector: 'app-new-customer',
templateUrl: './new-customer.component.html',
styleUrls: ['./new-customer.component.scss']
})
export class NewCustomerComponent implements OnInit {
dataSending = false;
customerId;
updatePerson;
updatedCustomer;
ready = false;
dialogView;
ref: ComponentRef<any>;
newCustomerForm: FormGroup;
counties; // list of counties
subCounties;
filteredCounties: Observable<string[]>;
constructor(
private _formBuilder: FormBuilder,
private router: Router,
private route: ActivatedRoute,
private customerService: CustomerService,
private countyService: CountyService,
private subCountyService: SubCountyService,
public dialogRef: MatDialogRef<NewCustomerComponent>,
@Inject(MAT_DIALOG_DATA) public display: any
) {
this.dialogView = display.view;
this.route.paramMap.subscribe((params) => {
this.customerId = params.get('customerId');
if (this.customerId) {
this.customerService.getCustomer(this.customerId).subscribe((response) => {
this.updatePerson = response;
this.newCustomerForm = this._formBuilder.group({
name: [this.updatePerson.name, Validators.required],
nationalId: [this.updatePerson.nationalId, Validators.required],
gender: [this.updatePerson.gender, Validators.required],
phone1: [this.updatePerson.phone1],
phone2: [this.updatePerson.phone2],
bishopName: [this.updatePerson.bishopName, Validators.required],
bishopPhone: [this.updatePerson.bishopPhone, Validators.required],
countyId: [this.updatePerson.countyId, Validators.required],
county: [this.updatePerson.county, Validators.required],
subCountyId: [this.updatePerson.subCountyId, Validators.required],
address: [this.updatePerson.address, Validators.required],
additionalInfo: [this.updatePerson.additionalInfo],
input1: [this.updatePerson.input1],
input2: [this.updatePerson.input2],
defaultingRecord: [''],
});
this.ready = true;
});
}
else {
this.ready = true;
this.newCustomerForm = this._formBuilder.group({
nationalId: ['', Validators.required],
name: ['', Validators.required],
gender: ['', Validators.required],
phone1: [''],
phone2: [''],
county: [''],
countyId: ['', Validators.required],
subCountyId: ['', Validators.required],
bishopName: ['', Validators.required],
bishopPhone: ['', Validators.required],
address: ['', Validators.required],
additionalInfo: [''],
input1: [''],
input2: [''],
defaultingRecord: [''],
});
}
});
}
// tslint:disable:typedef
ngOnInit() {
// Getting the list of counties
this.countyService.getCounties().subscribe((response) => {
this.counties = response;
this.newCustomerForm.patchValue({
county: response
});
if (!this.customerId) {
this.filteredCounties = this.newCustomerForm.get('county').valueChanges.pipe(
startWith(''),
map(value => typeof value === 'string' ? value : value.name),
map(value => this._filter(value))
);
}
}, error => {
this.counties = [
{
"countyId": 63,
"name": "Mombasa"
},
{
"countyId": 64,
"name": "Isiolo"
},
{
"countyId": 65,
"name": "Murang'a"
},
{
"countyId": 66,
"name": "Laikipia"
},
{
"countyId": 67,
"name": "Siaya"
},
{
"countyId": 68,
"name": "Kwale"
},
{
"countyId": 69,
"name": "Meru"
},
{
"countyId": 70,
"name": "Kiambu"
},
{
"countyId": 71,
"name": "Nakuru"
},
{
"countyId": 72,
"name": "Kisumu"
},
{
"countyId": 73,
"name": "Kilifi"
},
{
"countyId": 74,
"name": "Tharaka-Nithi"
},
{
"countyId": 75,
"name": "Turkana"
},
{
"countyId": 76,
"name": "Narok"
},
{
"countyId": 77,
"name": "Homa Bay"
},
{
"countyId": 78,
"name": "Tana River"
},
{
"countyId": 79,
"name": "Embu"
},
{
"countyId": 80,
"name": "West Pokot"
},
{
"countyId": 81,
"name": "Kajiado"
},
{
"countyId": 82,
"name": "Migori"
},
{
"countyId": 83,
"name": "Lamu"
},
{
"countyId": 84,
"name": "Kitui"
},
{
"countyId": 85,
"name": "Samburu"
},
{
"countyId": 86,
"name": "Kericho"
},
{
"countyId": 87,
"name": "Kisii"
},
{
"countyId": 88,
"name": "Taita-Taveta"
},
{
"countyId": 89,
"name": "Machakos"
},
{
"countyId": 90,
"name": "Trans Nzoia"
},
{
"countyId": 91,
"name": "Bomet"
},
{
"countyId": 92,
"name": "Nyamira"
},
{
"countyId": 93,
"name": "Garissa"
},
{
"countyId": 94,
"name": "Makueni"
},
{
"countyId": 95,
"name": "Uasin Gishu"
},
{
"countyId": 96,
"name": "Kakamega"
},
{
"countyId": 97,
"name": "Nairobi"
},
{
"countyId": 98,
"name": "Wajir"
},
{
"countyId": 99,
"name": "Nyandarua"
},
{
"countyId": 100,
"name": "Elgeyo-Marakwet"
},
{
"countyId": 101,
"name": "Vihiga"
},
{
"countyId": 102,
"name": "Mandera"
},
{
"countyId": 103,
"name": "Nyeri"
},
{
"countyId": 104,
"name": "Nandi"
},
{
"countyId": 105,
"name": "Bungoma"
},
{
"countyId": 106,
"name": "Marsabit"
},
{
"countyId": 107,
"name": "Kirinyaga"
},
{
"countyId": 108,
"name": "Baringo"
},
{
"countyId": 109,
"name": "Busia"
}
];
});
// Getting a list of sub-counties
this.subCountyService.getSubCounties().subscribe((response) => {
this.subCounties = response;
});
}
displayFn(county?: any): string | undefined {
return county ? county.name : undefined
}
private _filter(value) {
console.log('value: ', value);
const filterValue = value.toLowerCase();
return this.counties.filter(county => county.name.toLowerCase().indexOf(filterValue) === 0);
}
addCustomer(customer) {
console.log('Value of customer form before setting is: ', this.newCustomerForm.value);
const selectedCountyId = this.counties.filter(county => county.name === this.newCustomerForm.value.countyId)[0];
console.log('CountyId: ', selectedCountyId);
if (!selectedCountyId) {
PNotify.error({
title: 'Please selecte a valid county',
minHeight: '75px'
});
return;
}
this.newCustomerForm.patchValue({
countyId: selectedCountyId.countyId
});
customer.countyId = selectedCountyId.countyId;
console.log('Value of customer form after setting is: ', this.newCustomerForm.value);
this.dataSending = true;
this.customerService.addCustomer(customer).subscribe((response) => {
if (this.dialogView) {
PNotify.success({
title: 'Customer added Successfully',
minHeight: '75px'
});
this.dialogRef.close();
}
else {
PNotify.success({
title: 'Customer added Successfully',
text: 'Redirecting to list page',
minHeight: '75px'
});
this.dataSending = false;
document.getElementById('submitButton').style.display = 'initial';
this.router.navigate(['searchcustomer']);
}
}, (error) => {
console.log('Following error occured: ', error);
PNotify.error({
title: 'Error occured while adding customer',
text: 'Failed to add new customer',
minHeight: '75px'
});
this.dataSending = false;
});
}
updateCustomer(customer) {
this.dataSending = true;
this.updatedCustomer = this._formBuilder.group({
customerId: [this.customerId],
nationalId: [customer.nationalId],
name: [customer.name],
gender: [customer.gender],
phone1: [customer.phone1],
phone2: [customer.phone2],
countyId: [customer.countyId],
subCountyId: [customer.subCountyId],
address: [customer.address],
additionalInfo: [customer.additionalInfo],
bishopName: [customer.bishopName],
bishopPhone: [customer.bishopPhone],
input1: [customer.input1],
input2: [customer.input2],
});
this.customerService.updateCustomer(this.updatedCustomer.value, this.customerId).subscribe((response) => {
PNotify.success({
title: 'Customer updated Successfully',
text: 'Redirecting to list page',
minHeight: '75px'
});
this.dataSending = false;
this.router.navigate(['searchcustomer']);
}, (error) => {
console.log('An error occured while updating customer: ', error);
PNotify.error({
title: 'Error occured while updating customer',
text: 'Failed to update customer',
minHeight: '75px'
});
this.dataSending = false;
});
}
}
最佳答案
如果您为自动完成功能提供一个 ID,它就会显示该 ID。在您说它有效的第一张图像中,它看起来像它有效,但实际上它在做出选择时不存储 countyId
,而是存储 name
属性您已设置为值
。我认为它实际上也是您想要存储在那里的 id。
我认为最干净的解决方案是实际存储整个县对象。所以我建议如下:
<input type="text" matInput formControlName="county" [matAutocomplete]="auto">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let county of filteredCounties | async" [value]="county">
{{county.name}}
</mat-option>
</mat-autocomplete>
这样,我删除了 countyId
表单控件,而是添加了 county
,它存储整个对象并添加了 displayWith
以显示 名称
县的属性(property)。
然后修改valueChanges
以检查用户是否已键入或已提供对象:
// add the correct name of your form
this.filteredCounties = this.myForm
.get("county")
.valueChanges.pipe(
startWith(""),
map(value => typeof value === 'string' ? value : value.name),
map(value => this._filter(value))
);
以及模板中显示的displayFn
:
// don't use 'any' !!
displayFn(county?: any): string | undefined {
return county ? county.name : undefined
}
所以现在只剩下您要创建编辑表单的选项。如果您只有 countyId
属性,则可以使用 find
添加正确的对象。在此示例中,我在创建时设置它,但您可能会使用 setValue()
,但想法是相同的!
// replace 2 with the variable/prop you have the desired id
county: [this.counties.find(x => x.countyId === 2)],
现在你已经拥有了整个对象。提交表单时,如果您只需要表单控件中的 countyId
,则可以通过以下方式访问它:this.myForm.get('county').value.countyId
。
<强> STACKBLITZ 使用上面的代码。
关于javascript - 自动完成未从对象属性 Angular 中检测到正确的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59824810/
我需要将文本放在 中在一个 Div 中,在另一个 Div 中,在另一个 Div 中。所以这是它的样子: #document Change PIN
奇怪的事情发生了。 我有一个基本的 html 代码。 html,头部, body 。(因为我收到了一些反对票,这里是完整的代码) 这是我的CSS: html { backgroun
我正在尝试将 Assets 中的一组图像加载到 UICollectionview 中存在的 ImageView 中,但每当我运行应用程序时它都会显示错误。而且也没有显示图像。 我在ViewDidLoa
我需要根据带参数的 perl 脚本的输出更改一些环境变量。在 tcsh 中,我可以使用别名命令来评估 perl 脚本的输出。 tcsh: alias setsdk 'eval `/localhome/
我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!”来自右上方的以下 Ra
这是我的方法 void login(Event event);我想知道 Kotlin 中应该如何 最佳答案 在 Kotlin 中通配符运算符是 * 。它指示编译器它是未知的,但一旦知道,就不会有其他类
看下面的代码 for story in book if story.title.length < 140 - var story
我正在尝试用 C 语言学习字符串处理。我写了一个程序,它存储了一些音乐轨道,并帮助用户检查他/她想到的歌曲是否存在于存储的轨道中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr()
我正在学习 sscanf 并遇到如下格式字符串: sscanf("%[^:]:%[^*=]%*[*=]%n",a,b,&c); 我理解 %[^:] 部分意味着扫描直到遇到 ':' 并将其分配给 a。:
def char_check(x,y): if (str(x) in y or x.find(y) > -1) or (str(y) in x or y.find(x) > -1):
我有一种情况,我想将文本文件中的现有行包含到一个新 block 中。 line 1 line 2 line in block line 3 line 4 应该变成 line 1 line 2 line
我有一个新项目,我正在尝试设置 Django 调试工具栏。首先,我尝试了快速设置,它只涉及将 'debug_toolbar' 添加到我的已安装应用程序列表中。有了这个,当我转到我的根 URL 时,调试
在 Matlab 中,如果我有一个函数 f,例如签名是 f(a,b,c),我可以创建一个只有一个变量 b 的函数,它将使用固定的 a=a1 和 c=c1 调用 f: g = @(b) f(a1, b,
我不明白为什么 ForEach 中的元素之间有多余的垂直间距在 VStack 里面在 ScrollView 里面使用 GeometryReader 时渲染自定义水平分隔线。 Scrol
我想知道,是否有关于何时使用 session 和 cookie 的指南或最佳实践? 什么应该和什么不应该存储在其中?谢谢! 最佳答案 这些文档很好地了解了 session cookie 的安全问题以及
我在 scipy/numpy 中有一个 Nx3 矩阵,我想用它制作一个 3 维条形图,其中 X 轴和 Y 轴由矩阵的第一列和第二列的值、高度确定每个条形的 是矩阵中的第三列,条形的数量由 N 确定。
假设我用两种不同的方式初始化信号量 sem_init(&randomsem,0,1) sem_init(&randomsem,0,0) 现在, sem_wait(&randomsem) 在这两种情况下
我怀疑该值如何存储在“WORD”中,因为 PStr 包含实际输出。? 既然Pstr中存储的是小写到大写的字母,那么在printf中如何将其给出为“WORD”。有人可以吗?解释一下? #include
我有一个 3x3 数组: var my_array = [[0,1,2], [3,4,5], [6,7,8]]; 并想获得它的第一个 2
我意识到您可以使用如下方式轻松检查焦点: var hasFocus = true; $(window).blur(function(){ hasFocus = false; }); $(win
我是一名优秀的程序员,十分优秀!