Я хочу обновить данные формы, когда я обновляю раскрывающийся список выберите и нажмите кнопку отправки. Я попытался реализовать это:
Конструктор:
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>
Строки в поле ввода обновляются, но я не могу понять, почему, когда я выбираю другое значение из раскрывающегося списка, оно не обновляется.
Можете ли вы дать мне совет, в чем я ошибаюсь?
в бэкэнде я получаю эту ошибку pastebin.com/35z1vzvx
это выглядит ошибкой из-за сохранения данных. В соответствии с ситуацией, которую вы объяснили в своем вопросе, это может быть ошибка, возникающая при обновлении merchant_id в базе данных. Оставьте пользовательский интерфейс как есть, и сначала вы должны решить проблему.
Как говорится в предупреждающем сообщении после сообщения об ошибке, в вашем коде есть проблема, связанная с какой-то блокировкой. Я не уверен в спящем режиме, но думаю, что ответ здесь может быть связано с вашей проблемой. Я думаю, что query.setLockMode(LockModeType.PESSIMISTIC_WRITE); и entityManager.lock(tsn, LockModeType.PESSIMISTIC_WRITE); - суть ответа.





ссылка на https://angular.io/guide/forms Каждый элемент ввода имеет свойство name, которое требуется формам 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.info(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.info(merchant);
}
Хорошо, но я не понимаю, как это может решить проблему с кодом.
нет, наверное потому, что логика для обновления SQL не реализована?
Можете ли вы добавить свою модель данных?
Пост обновлен. Что-нибудь еще, что вы хотели бы увидеть?
Я думаю, что [(ngModel)] = "contract.merchant_id" должно быть [(ngModel)] = "contract.id"
Позвольте нам продолжить обсуждение в чате.
Давайте оставим это простым и внесем изменения в select box как - Используйте merchant в качестве значения вместо merchant id. Он обновит весь объект merchant, а остальная часть field будет обновлена автоматически.
<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>
compareFn(a, b) {
if (!a || !b) {
return false;
} else {
return a.merchant_id === b.merchant_id; //you can use other property also
}
}
Код, который вы предоставили, мне подходит. Вы тестировали API, которые вызываются в методах сохранения, сохранения и получения ContractService, без интеграции с пользовательским интерфейсом? Они работают особенно с merchant_id?