Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
315 views
in Technique[技术] by (71.8m points)

html - Drop Down List in Angular 2 Model Driven Form

I have a model driven form in which I would like to add a drop down list containing several options. The options are from a pre-fetched list, and the model of the form is injected to the component. The form is loaded correctly: All the fields from the model are filled properly, abd the list of options for the drop-down list is also loaded correctly.
The only problem is that I can't set the selected value of the list, and it appears with an empty value at first.

Here, I am loading the HMOs list, then loading the patient, and only then creating the form.
All the values of the form (name, id, etc. which are omitted here) are loaded correctly into the form.
The drop-down list in the form is filled correctly: All HMOs are populating the list.
Still, the selected value in the list is missing, and the lost is loaded with no initial value.
For debugging purposes, I have replaced the boolean condition in the option tag: patient.hmo.uid == hmo.uid to a function call: isSelected(hmo).
This function essentially does the same comparison and returns its value, but first logs it. Indeed I see that the option with the correct hmo gets a true value and all other options get false values, meaning all data is loaded correctly.

Also, when I set the [selected]="true" (always to be true), I do see the change affects: The last option is selected (the default in HTML).

So where am I wrong? How should I set the selected option correctly?

Code for the component (all fields except HMO are omitted):

import {Component, Input, Inject, OnInit} from "@angular/core";
import {
  FormGroup,
  FormControl,
  REACTIVE_FORM_DIRECTIVES,
  Validators,
  FormBuilder,
  FormArray
} from "@angular/forms";
import {Patient} from "./patient";
import {PatientsService} from "./patients.service";
import {Hmo} from "../hmos/hmo";
import {HmosService} from "../hmos/hmos.service";
import {Doctor} from "../doctors/doctor";
import {DoctorsService} from "../doctors/doctors.service";
import {Router, ActivatedRoute} from "@angular/router";
import {Subscription} from "rxjs/Rx";
import {Response} from "@angular/http";
import {JavaDate} from "./java-date";

@Component({
  moduleId: module.id,
  selector: 'gy-patient-edit',
  templateUrl: 'patient-edit.component.html',
  directives: [REACTIVE_FORM_DIRECTIVES],
})
export class PatientEditComponent implements OnInit {

  patientForm: FormGroup;

  @Input() patient: Patient;
  private hmos: Hmo[];
  private patientUid: number;
  private showForm: boolean = false;

  constructor(@Inject(PatientsService) private patientsService: PatientsService,
              @Inject(HmosService) private hmosService: HmosService,
              @Inject(ActivatedRoute) private route: ActivatedRoute,
              @Inject(FormBuilder) private formBuilder: FormBuilder) {
  }

  ngOnInit(): any {
    this.subscription = this.route.params.subscribe(
      (params: any) => {
        this.patientUid = params['id']; //Getting the UID from the URL
      }
    );
    this.hmosService.hmosChanged.subscribe(
      (hmos: Hmo[]) => {
        this.hmos = hmos; //Fetching available HMOs
      }
    );
    this.hmosService.fetchHmos();
    this.patientsService.fetchPatient(this.patientUid) //Fetching the Patient
      .map((response: Response) => response.json())
      .subscribe((data: Patient) => {
        this.patient = data;
        this.restartForm(); //Only required so the form will ne initialized only after the patient is received from the server
      });
  }

  restartForm(){
    this.patientForm = this.formBuilder.group({
      hmo: [this.patient.hmo]]
    });
    this.showForm = true;
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

}

Code for the HTML form:

<div class="row" *ngIf="showForm">
  <div class="col-xs-12" *ngIf="showForm">
    <form [formGroup]="patientForm" (ngSubmit)="onSubmit()">
      <div class="form-group">
        <label for="hmo">HMO</label>
        <select formControlName="hmo" id="hmo">
          <option *ngFor="let hmo of hmos"
                  [value]="hmo.uid" [selected]="patient.hmo.uid == hmo.uid">
            {{hmo.name}}
          </option>
        </select>
    </form>
  </div>
</div>

Code for Patient:

import {Hmo} from "../hmos/hmo";
export class Patient {
  constructor(public hmo: Hmo) {

  }
}

Code for Hmo:

export class Hmo{
  constructor(public uid: number, public name: string){}
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The selected option is calculated by comparing the <option>'s value with <select>'s value. In light of that, to mark an <option> as selected, we need to make sure the wrapping <select> is containing the same value, which in turn requires the correct value of the corresponding form control in your model.

Your code can be slightly modified as follow:

  restartForm(){
    this.patientForm = this.formBuilder.group({
      hmo: [this.patient.hmo.uid]
    });
    this.showForm = true;
  }

And Template:

<select formControlName="hmo" id="hmo">
   <option *ngFor="let hmo of hmos"
     [value]="hmo.uid">
        {{hmo.name}}
   </option>
</select>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...