Angular 6反应形式-根据条件动态设置<select> FormControl的选定<option>

时间:2018-09-18 13:04:38

标签: typescript angular6 angular-reactive-forms

我需要知道如何根据条件动态设置                             这是form.component.ts: customerForm:FormGroup; 客户:客户[] = [ {“ id”:1,     “ name”:“ Meghan Castellano”,     “ orderIds”:[1,2]}, {“ id”:2,     “ name”:“ Monika Weiss”,     “ orderIds”:[3,4]}]; orders:Order [] = [{“ id”:1},{“ id”:2},{“ id”:3},{“ id”:4}]]; filteredOrders:Order []; 构造函数(私有路由:ActivatedRoute,             私人fb:FormBuilder){} ngOnInit(){     this.customerForm = this.fb.group({         顾客: '',         订单: '' });     让customerId = this.route.snapshot.getParam('id');     如果(customerId == 0){         this.customerForm.patchValue({             客户:“(新客户)”,             order:“(new order)”});     }     其他     {         让客户= this.customers [customerId];         this.customerForm.patchValue({客户:customer.name});         如果(customer.orderIds.length!= 0){             this.filteredOrders = getCustomersOrders(customer);         this.customerForm.patchValue({             订单:this.filteredOrders [0] .id}         }     } } getCustomersOrders(客户:客户):订单[] {     let命令:Order [];     for(var id = 0; id i.id == orderId);         orders.push(命令); }     退货订单; } 目前,我正在路由到表单,并提供带有URL的ID。客户下拉菜单根据URL中的ID选择正确的客户。 但是,仅正确填充了订单下拉菜单,但是选择不起作用。根本没有选择任何选项。 如果我替换此语句中的值: this.customerForm.patchValue({订单:this.filteredOrders [0] .id} 并已在html中指定“(新订单)”字符串: this.customerForm.patchValue({order:“(new order)”}) 有用。在订单下拉菜单中选择字符串“(新订单)”。只是对filteredOrders不起作用。 我在这里做错了什么?在这里我可能需要一种完全不同的方法吗?

3 个答案:

答案 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;
  }
}
相关问题