使用选定的下拉菜单提交表单数据



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

施工单位:

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>

输入字段中的字符串会更新,但我不知道为什么当我从下拉列表中选择不同的值时,它不会更新。

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

对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>

作为一种通用

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

让我们保持简单,并将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
}
}