答案 0 :(得分:3)
好吧,几个小时后我明白了。这是我更新的.html和.ts文件,供您参考:
HTML:
<form class="form-container" [formGroup]="customerForm">
<select formControlName="customer" (change)="onCustomerChanged($event)">
<option>(new customer)</option>
<option *ngFor="let customer of customers" [value]="customer.name">
{{customer.name}}
</option>
</select>
<select formControlName="order">
<option>(new order))</option>
<option *ngFor="let order of filteredOrders" [value]="order.id">
{{order.id}}</option>
</select>
</form>
.ts文件
export class CustomerFormComponent implements OnInit {
customerForm: FormGroup;
selectedCustomer: Customer;
filteredOrders: Order[];
customers: Customer[] = [...];
orders: Order[] = [...];
constructor(private route: ActivatedRoute,
private fb: FormBuilder) { }
ngOnInit() {
this.customerForm = this.fb.group({
customer: "",
order: ""
});
let customerId = Number(this.route.snapshot.paramMap.get('customerId'));
this.setFormControlValues(customerId);
}
setFormControlValues(customerId: number) {
if (customerId == 0) {
this.customerForm.get('customer').setValue("(new customer)");
this.customerForm.get('order').setValue("(new order)");
}
else {
this.selectedCustomer = this.customers.find(i => i.id == customerId);
this.filteredOrders = this.getCustomerOrders(this.selectedCustomer);
this.customerForm.get('customer').setValue(this.selectedCustomer.name);
this.customerForm.get('order').setValue(this.filteredOrders[0].orderNumber);
}
}
getCustomerOrders(customer: Customer) : Order[] {
let orders: Order[] = [];
for (var id = 0; id < customer.orderIds.length; id++) {
let orderId = customer.orderIds[id];
orders.push(this.orders.find(i => i.id == orderId));
}
return orders;
}
onCustomerChanged(event: any) {
this.selectedCustomer = this.customers.find(n => n.name == event.target.value);
this.setFormControlValues(this.selectedCustomer.id);
}
}
如您所见,在HTML中,我现在使用“ [value]”而不是“ [ngValue]”和“ customer.name” /“ order.id”,而不仅仅是“ customer” /“ order”。 / p>
在.ts文件中,我摆脱了“ patchValue()”方法,而引入了“ setValue”方法。
这是有效的stackblitz示例:
https://stackblitz.com/edit/angular-conditionaldropdown-gnajge
答案 1 :(得分:1)
我认为问题出在订单选择器中选择的对象(实际上也是在客户选择器中)。
<option [ngValue]="order" *ngFor="let order of filteredOrders">
{{order.id}}
</option>
这意味着将选择整个order
对象,而不仅是订单ID。在这种情况下,如果您尝试仅使用order.id
来修补值,则它将不起作用:选择器将等待Order
对象,而不是order.id
。
我对您在问题中输入的代码的有效版本进行了快速的堆栈闪电:https://stackblitz.com/edit/angular-drop-dowb。唯一真正的区别是
this.customerForm.patchValue({
orders: this.filteredOrders[0]
});
代替
this.customerForm.patchValue({
orders: this.filteredOrders[0].id }
});
所以,我已经更新了堆叠闪电战。
要在orders
中使customer
字段具有正确的值,您需要在(change)
字段中添加select
。
<select formControlName="customers" (change)="updateOrders($event)">
<option [ngValue]="null">(new customer)</option>
<option [value]="customer.id" *ngFor="let customer of customers" >
{{customer.name}}
</option>
</select>
不要忘记将客户id
字段作为值而不是customer
传递-Angular似乎不喜欢它。然后,使用id
值,您需要在updateOrders
中添加一个component.ts
函数。
updateOrders(event) {
const index = this.customers.findIndex(item => item.id == event.target.value);
if (index === -1) {
this.customerForm.controls.orders.setValue(null);
return;
}
this.filteredOrders = this.getCustomersOrders(this.customers[index]);
this.customerForm.controls.orders.setValue(this.filteredOrders[0]);
}
在id
不在客户列表中的情况下,您将仅使用orders
值(对应于您的null
)更新(new order)
。并且如果id
在客户列表中,那么您将更新filteredOrders
。
答案 2 :(得分:0)
如果您使用 [ngValue]
,则可以在 [compareWith]
元素上使用 select
,传入比较函数以确定是否选择了该值。使用 [ngValue]
允许复杂对象超过 [value]
字符串。
<form [formGroup]="customerForm">
<select [compareWith]="compareCustomers" formControlName="customers">
<option>(new customer)</option>
<option [ngValue]="customer" *ngFor="let customer of customers">
{{customer.name}}
</option>
</select>
<select [compareWith]="compareOrders" formControlName="orders">
<option>(new order)</option>
<option [ngValue]="order" *ngFor="let order of filteredOrders">
{{order.id}}
</option>
</select>
</form>
export class SomeComponent {
public compareCustomer(a: Customer, b: Customer): boolean {
return a.id === b.id;
}
public compareOrders(a: Order, b: Order): boolean {
return a.id === b.id;
}
}