Заполните раскрывающийся список из службы после загрузки формы
У меня есть проблема, аналогичная описанной в раскрывающемся списке в Angular 2 Model Driven Form (хотя с гораздо более простой привязкой модели к блоку выбора).
Шаблон очень прост, в основном это список 'Dear x', где x предоставляется сервисом:
<form novalidate [formGroup]="myForm">
<div class="form-group">
<label for="salutation">Dear ...</label>
<select id="salutation"
class="form-control"
formControlName="salutation">
<option value="">Please select how to address the customer</option>
<option *ngFor="let sal of salutations"
[value]="sal">{{sal}}
</option>
</select>
</div>
</form>
В компонентах я подписываюсь на сервис, который получает данные для этого поля выбора (console.log
показывает, что действительно данные поступают).
ngOnInit() {
this.createFormControls();
this.createForm();
this.proposalStateService.emitProposal.subscribe(
data => {
console.log('subscribe fired: ');
console.log(data);
this.salutations = [
'Mr & Mrs ' + data.last_name,
'Mrs ' + data.last_name,
'Ms ' + data.last_name,
'Mr ' + data.last_name,
data.first_name
];
}
);
}
createFormControls() {
this.salutation = new FormControl(this.salutations, Validators.required);
}
createForm() {
this.myForm = new FormGroup({
salutation: this.salutation
});
}
Я пробовал эти методы, чтобы получить форму для обновления со значениями из службы, но ни один из них, похоже, не работает:
Сбросить группу
this.myForm = this.formBuilder.group({ salutation: [this.salutations] });
Укажите значение в форме
this.myForm.patchValue(this.salutation, this.salutations);
Установите значение на элементе управления
this.salutation.setValue(this.salutations);
Установите значение через форму
this.myForm.controls['salutation'].setValue(this.salutations);
Я явно что-то упускаю... но что?
РЕДАКТИРОВАТЬ В ОРИГИНАЛЬНЫЙ ВОПРОС
Иногда консоль показывала поступающие данные, но после очистки моего кода и после дальнейшего тестирования console.log
события теперь не отображаются при загрузке этого компонента. Я думаю, что это должно быть проблема синхронизации - возможно, компонент загружается ПОСЛЕ службы, которая отправляет данные, которые ему нужны, уже запущены.
Этот компонент загружается родительским компонентом в событие навигации, например:
/parent.component.ts
ngOnInit() {
this.newProposal = new Proposal;
this.newProposal.step = 1;
this.proposalStateService.emitProposal.subscribe(
data => {
this.router.navigate(['pages/proposals/new/step' + data.step]);
}
);
Этот emitProposal запускается в этом компоненте пользователем, сбрасывающим на него некоторые данные, в результате чего вызывается этот метод:
private initProposal(customer, step) {
this.newProposal.first_name = customer.first_name;
this.newProposal.last_name = customer.last_name;
this.newProposal.customer_id = customer.id;
this.newProposal.email = customer.email;
this.newProposal.mobile = customer.mobile;
this.newProposal.status = 'Draft';
this.newProposal.step = step;
this.proposalStateService.pushProposal(this.newProposal);
}
Таким образом, кажется, что "pushProposal" запускается до загрузки дочернего компонента, может ли это быть проблемой?
(теперь мне интересно, как в журнале ранее отображались полученные данные, ха, что, черт возьми, я изменил, когда писал этот вопрос!?)
1 ответ
Итак, я нашел решение - спасибо тем, кто помог с комментариями и ссылками на другие вопросы.
Когда я перемещаю форму к родителю, данные поступают и загружаются в форму с помощью опции (D):
this.myForm.controls['salutation'].setValue(this.salutations);
Но, очевидно, я не хочу этого там, и загружать его только после того, как родитель перешел.
Таким образом, решение этой проблемы состояло в том, чтобы улучшить сервис, позволив ему "хранить" объект, выдвинутый родителем. Таким образом, излучатель изменился с этого:
emitProposal = new EventEmitter<Proposal>();
pushProposal(value: Proposal) {
this.emitProposal.emit(value);
}
к этому:
currentProposal: Proposal;
getCurrentProposal() {
return this.currentProposal;
}
emitProposal = new EventEmitter<Proposal>();
pushProposal(value: Proposal) {
this.currentProposal = value;
this.emitProposal.emit(value);
}
и форма теперь просто должна сделать это:
ngOnInit() {
this.createFormControls();
this.createForm();
this.proposal = this.proposalStateService.getCurrentProposal();
this.salutations = [
'Mr & Mrs ' + this.proposal.last_name,
'Mrs ' + this.proposal.last_name,
'Ms ' + this.proposal.last_name,
'Mr ' + this.proposal.last_name,
this.proposal.first_name
];
}