首页 > 解决方案 > 使用选定的下拉菜单提交表单数据

问题描述

当我更新选择下拉菜单并单击提交按钮时,我想更新表单数据。我试图实现这一点:

构造函数:

export class Contract {
  constructor(
    public id: string,
    public enabled: boolean,
    public name: string,
    public merchant_id: number,    
    public gateway: string,
    public descriptor: string
  ) {}
}

服务:

@Injectable({
  providedIn: 'root'
})
export class ContractService {

  constructor(private http: HttpClient) {
  }

  search(filter: ContractFilter, page: number, size: number): Observable<PagedResult<Contract>> {
    let params = this.buildFilterParams(filter);
    let pagedFilter = HttpUtils.appendPageParams(params, page, size);

    return this.http.get<PagedResult<Contract>>(environment.api.urls.contracts.base, {params: pagedFilter});
  }

  private buildFilterParams(filter: ContractFilter): HttpParams {
    let params = new HttpParams();

    if (filter.name) {
      params = params.append('name', filter.name);
    }
    if (filter.id) {
      params = params.append('id', filter.id);
    }

    if (filter.from) {
      params = params.append('from', DateUtil.offsetDate(filter.from.toISOString()));
    }

    if (filter.to) {
      params = params.append('to', DateUtil.offsetDate(filter.to.toISOString()));
    }
    return params;
  }

  save(contract: Contract) {
    return this.http.post(environment.api.urls.contracts.base, contract);
  }

  persist(contract: Contract) {
    return this.http.post(environment.api.urls.contracts.persist(contract.id), contract);
  }

  get(contractId: string): Observable<Contract> {
    return this.http.get<Contract>(environment.api.urls.contracts.get(contractId));
  }

  export() {
    return this.http.get(environment.api.urls.contracts.export,  { responseType: 'blob' });
  }
}

零件:

@Component({
  selector: 'app-contract',
  templateUrl: './contract.component.html',
  styleUrls: ['./contract.component.scss']
})
export class ContractComponent implements OnInit {

  contract: Contract = new Contract(null, null, null, null, null);
  merchants: MerchantList[];

  edit = false;

  valueExists = false;

  constructor(private contractService: ContractService,
              private merchantService: MerchantService,
              private router: Router,
              private route: ActivatedRoute) {
  }

  ngOnInit() {

    this.route.params.pipe(
      flatMap(params => {
        if (params['id']) {
          return this.contractService.get(params['id']);
        } else {
          return of(null);
        }
      })
    ).subscribe(value => {
      if (value != null) {
        this.contract = value;
        this.edit = true;
      }
    });

    this.merchantService.getMerchantsList()
     .subscribe(value => {
        if (value != null) {
          this.merchants = value;
        }
    });
  }

  clear() {
    this.contract.name = null;
  }

  submit() {
    if (this.edit) {
      this.contractService.persist(this.contract).subscribe(() => {
        this.router.navigate(['panel', 'contracts', 'list']);
      })
    } else {
      this.contractService.save(this.contract).subscribe(() => {
          this.router.navigate(['panel', 'contracts', 'list']);
        },
        error => this.handleError(error.error));
    }
  }

  handleError(error: string) {
    if (error === 'TRANSACTION_EXISTS') {
      this.valueExists = true;
    }
  }
}

HTML 代码:

<h1 class="title">New Contract</h1>

<form class="grid-wrapper" #f="ngForm">
  <div *ngIf="edit" class="form-group id">
    <label for="id">Transaction ID</label>
    <input id="id" type="text" name="id" class="form-control" disabled [(ngModel)]="contract.id">
  </div>

  <div class="form-group name">
    <label for="name">Contract name</label>
    <input id="name" type="text" name="name" class="form-control" required [(ngModel)]="contract.name">
  </div>

  <div class="form-group type">
    <div class="input-group-prepend">
      <label for="type">Merchant</label>
    </div>
    <select class="custom-select" name="type" [(ngModel)]="contract.merchant_id" id="merchant_id" required>
      <option selected>Please Select...</option>
      <option [value]="merchant.id" *ngFor="let merchant of merchants">{{ merchant.name }}</option>
    </select>
  </div>

  <div class="btn-row">
    <button class="btn btn-primary" [disabled]="f.invalid" (click)="submit()">Submit</button>
    <button class="btn btn-secondary" (click)="clear()">Clear</button>
  </div>

</form>

输入字段中的字符串已更新,但我找不到为什么当我从下拉值中选择不同的值时它没有更新。

你能给我一些建议,我哪里错了吗?

标签: angulartypescript

解决方案


让我们保持简单,并在select boxas-Use merchantas a value 而不是merchant id. 它将更新整个merchant对象,其余的field将自动更新。

html

 <select class="custom-select" name="type" 
        [(ngModel)]="contract" 
        [compareWith]="compareFn"
         id="merchant_id" required>
      <option selected>Please Select...</option>
      <option [ngValue]="merchant" *ngFor="let merchant of merchants">{{ merchant.name }}</option>
    </select>

ts

compareFn(a, b) {
    if (!a || !b) {
      return false;
    } else {
      return a.merchant_id === b.merchant_id; //you can use other property also
    }
  }

推荐阅读