Заполните раскрывающийся список из службы после загрузки формы

У меня есть проблема, аналогичная описанной в раскрывающемся списке в 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
    });
  }

Я пробовал эти методы, чтобы получить форму для обновления со значениями из службы, но ни один из них, похоже, не работает:

  1. Сбросить группу

    this.myForm = this.formBuilder.group({
      salutation: [this.salutations]
    });
    
  2. Укажите значение в форме

    this.myForm.patchValue(this.salutation, this.salutations);
    
  3. Установите значение на элементе управления

    this.salutation.setValue(this.salutations);
    
  4. Установите значение через форму

    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
    ];
 }
Другие вопросы по тегам