提交带有选定下拉菜单的表单数据

时间:2018-11-04 08:27:08

标签: angular typescript

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

构造函数:

const data = [
    {date:"1 Nov", foo: 123},
    {date:"1 Nov", bar: 456},
    {date:"2 Nov", foo: 234}, 
    {date:"2 Nov", bar: 567}
];

const output = data.reduce((result, item) => {
  
  const i = result.findIndex(resultItem => resultItem.date === item.date)
    
  if(i === -1) {
    // No item in current result array found that matches the date of item
    // so add item to result array
    result.push(item)
  }
  else {
    // An item found with date matching item in current result so combine 
    // the two into a new object and assign this back into our result 
    // array
    result[i] = { ...result[i], ...item }
  }
  
  return result
}, [])

console.log(output);

服务:

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' });
  }
}

HTML代码:

@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;
    }
  }
}

输入字段中的字符串已更新,但我找不到从下拉值中选择其他值时未更新的原因。

你能给我一些我错了的建议吗?

3 个答案:

答案 0 :(得分:0)

https://angular.io/guide/forms的引用 每个输入元素都有一个名称属性,Angular表单需要使用该属性来将控件注册到表单中。

您的问题在HTML模板中 您必须将name属性从“ type”更改为与模型相同的“ merchant_id”。

<select class="custom-select" name="merchant_id" [(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>

答案 1 :(得分:0)

一般

HTML

<select [(ngModel)]="selectedOption" name="first" (change)="selected()">
   <option *ngFor="let o of options">
      {{o.name}}
   </option>
</select>

打字稿

selectedOption: string;
options = [
    { name: "option1", value: 1 },
    { name: "option2", value: 2 }
]

selected(){
   console.log(this.selectedOption)
}

对于您的情况,请尝试

HTML

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

打字稿

onChange(merchant) {
   console.log(merchant);
}

答案 2 :(得分:0)

让它保持简单,并在select box中进行如下更改-使用merchant作为值而不是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
    }
  }