Angular 4 @ngui-автозаполнение

Я пытаюсь использовать библиотеку @ngui-autocomplete в проекте Angular 4. Я использую форму как для создания новых записей в базе данных, так и для обновления/редактирования существующих. Код для моего ввода автозаполнения следующий:

<div [ngClass]="{
              'form-group': true, 'row' : true,
              'has-danger': incidentForm.get('doctor').invalid && ( incidentForm.get('doctor').touched || incidentForm.get('doctor').dirty ),
              'has-success': incidentForm.get('doctor').valid && ( incidentForm.get('doctor').dirty || incidentForm.get('doctor').touched )
           }">
  <label for="doctor" class="col-sm-2 col-form-label">Ιατρός:</label>
  <div class="col-6">

    <input ngui-auto-complete [ngClass]="{
              'form-control': true,
              'form-control-danger': incidentForm.get('doctor').invalid && ( incidentForm.get('doctor').touched || incidentForm.get('doctor').dirty ),
              'form-control-success': incidentForm.get('doctor').valid && ( incidentForm.get('doctor').dirty || incidentForm.get('doctor').touched )
              }"
           name="doctor" formControlName="doctor"
           id="doctor" [source]="doctors"
           autocomplete="off"
           [list-formatter]="'lastName firstName'"
           value-formatter="lastName firstName"
           select-value-of="id"
           required >

    <!-- VALIDATION -->
    <div class="form-control-feedback"
         *ngIf="incidentForm.get('doctor').hasError('required') && incidentForm.get('doctor').touched">
      {{ validationMessages.doctor.required }}
    </div>
    <!-- END OF VALIDATION -->
  </div>
</div>

Мой код form.ts:

import {Component, OnInit} from '@angular/core';
import {IncidentsService} from '../incidents.service';
import {Patient} from '../../patients/patient';
import {Doctor} from '../../doctors/doctor';
import {Clinic} from '../../clinics/clinic';
import {Incident} from '../incident';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import {SigningDoctor} from '../../signing-doctors/signing-doctor';
import {HttpErrorResponse} from '@angular/common/http';
import {ActivatedRoute} from '@angular/router';

import 'rxjs/add/operator/startWith';
import 'rxjs/add/operator/map';
import {Observable} from 'rxjs/Observable';
import {DomSanitizer, SafeHtml} from '@angular/platform-browser';


@Component({
  selector: 'app-incident-form',
  templateUrl: './incident-form.component.html',
  styleUrls: ['./incident-form.component.css']
})
export class IncidentFormComponent implements OnInit {

  private incident: Incident;
  private id;

  private incidentForm: FormGroup;
  private patients: Patient[] = [];
  private doctors: Doctor[] = [];
  private clinics: Clinic[] = [];
  private signingDoctors: SigningDoctor[] = [];
  private doctor: Doctor;

  private errorMsg;


  constructor(private incidentsService: IncidentsService, private formBuilder: FormBuilder,  private route: ActivatedRoute,  private sanitizer: DomSanitizer) {
    this.createForm();
  }

  createForm() {

    this.incidentForm = this.formBuilder.group({
      protocolNo: ['', [Validators.required, Validators.pattern('^[0-9]{1,}')]],
      date: ['', Validators.required],
      mikro: ['', Validators.required],
      makro: ['', Validators.required],
      yliko: ['', Validators.required],
      anoso: [''],
      histo: [''],
      klinikesPlirofories: [''],
      simpliromatikiEkthesi: [''],
      symperasma: ['', Validators.required],
      patient: ['', Validators.required],
      doctor: ['', Validators.required],
      clinic: [''],
      isPayed: ['', Validators.required],
      signingDoctor: ['', Validators.required]
    });

  }


  ngOnInit() {

    this.parseID();
    this.getIncidentByID();
    this.getRelatedData();
  }

  private parseID() {

    this.route.params
      .catch(error => {
        console.log('error catched', error);

        return Observable.of({description: error});
      })
      .subscribe(
        params => {
          this.id = +params['id'];
        }
      );
  }

  private setFormValues(response){
    this.incidentForm.get('protocolNo').setValue(response.protocolNo);
    this.incidentForm.get('date').setValue(response.date);
    this.incidentForm.get('mikro').setValue(response.mikro);
    this.incidentForm.get('makro').setValue(response.makro);
    this.incidentForm.get('yliko').setValue(response.yliko);
    this.incidentForm.get('anoso').setValue(response.anoso);
    this.incidentForm.get('histo').setValue(response.histo);
    this.incidentForm.get('klinikesPlirofories').setValue(response.klinikesPlirofories);
    this.incidentForm.get('simpliromatikiEkthesi').setValue(response.simpliromatikiEkthesi);
    this.incidentForm.get('symperasma').setValue(response.symperasma);
    this.incidentForm.get('isPayed').setValue(response.isPayed);
    this.incidentForm.get('doctor').setValue(response.doctor);
  }

  autocompleListFormatter = (data: any) => {
    let html = `${data.lastName} ${data.firstName}`;
    return this.sanitizer.bypassSecurityTrustHtml(html);
  }


  private getIncidentByID() {

    this.incidentsService.getIncidentByID(this.id)
      .subscribe(
        response => {
          this.incident = response;
          this.setFormValues(response);

        },
        (err: HttpErrorResponse) => {
          if (err.error instanceof Error) {
            // A client-side or network error occurred. Handle it accordingly.
            console.log('An error occurred:', err.error.message);
          } else {
            // The backend returned an unsuccessful response code.
            // The response body may contain clues as to what went wrong,
            console.log(`Backend returned code ${err.status}, body was: ${err.error}`);
          }
        });
  }

  getRelatedData() {

    this.incidentsService.getRelatedData().subscribe(
      results => {
        this.patients = results[0];
        this.doctors = results[1];
        this.clinics = results[2];
        this.signingDoctors = results[3];
      },
      (err: HttpErrorResponse) => IncidentFormComponent.handleError
    );
  }

  submitForm() {

    this.incidentsService.submitForm(this.incidentForm.value).subscribe(
      res => {
        // this.incident = res;
        console.log('Submit Form Response: ' + JSON.stringify(res));

        this.incidentForm.reset();
        // this.createForm();
      },
      (err: HttpErrorResponse) => IncidentFormComponent.handleError
    );

  }

  static handleError(err) {

    if (err.error instanceof Error) {
      // A client-side or network error occurred. Handle it accordingly.
      console.log('An error occurred:', err.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.log(`Backend returned code ${err.status}, body was: ${err.error}`);
    }

  }

  validationMessages = {
    protocolNo: {
      required: 'Ο Αριθμός Πρωτοκόλλου είναι υποχρεωτικός.',
      pattern: 'Ο Αριθμός Πρωτοκόλλου Έχει Λάθος Μορφή.'
    },
    date: {
      required: 'Η Ημερομηνία Είναι Υποχρεωτική. ',
      pattern: 'Λάθος Μορφή Ημερομηνίας.'
    },
    symperasma: {
      required: 'Το Συμπερασμα είναι Υποχρεωτικό.',
    },
    patient: {
      required: 'Η Επιλογή Ασθενή Είναι Υποχρεωτική.'
    },
    doctor: {
      required: 'Η Επιλογή Ιατρού Είναι Υποχρεωτική.'
    },
    signingDoctor: {
      required: 'Η Επιλογή Υπογράφων Ιατρού Είναι Υποχρεωτική.'
    },
    yliko: {
      required: 'Το πεδίο υλικό είναι υποχρεωτικό.'
    },
    mikro: {
      required: 'Το πεδίο μίκροσκοπικά είναι υποχρεωτικό.'
    },
    makro: {
      required: 'Το πεδίο μακροσκοπικά είναι υποχρεωτικό.'
    },
    isPayed: {
      required: 'Το πεδίο πληρωμή είναι υποχρεωτικό.'
    },

    success: 'Yeah'
  };

}

Для создания записей все работает как положено. Однако, когда я обновляю существующие записи, я хочу установить значение для компонента ввода автозаполнения с помощью команды

this.incidentForm.get('doctor').setValue(response.doctor);

в то время как form.value верен внутри поля ввода, я получаю: [object Object] вместо «lastName firstName», как указано в команде

value-formatter="lastName firstName"

Я полагаю, что мне не хватает чего-то очень простого, но я не могу этого понять.


person mixtou    schedule 31.08.2017    source источник
comment
можете ли вы вставить код для службы getIncidentByID в * и ответ json, который приходит от этой службы?   -  person Vikhyath Maiya    schedule 31.08.2017
comment
Объект получен правильно. Я вижу это в form.value. Проблема заключается в поле автозаполнения ввода, которое вместо отображения lastName firstName отображает [object Object]   -  person mixtou    schedule 02.09.2017
comment
Я понял, вот почему я попросил вас вставить ответ JSON и увидеть вице-код   -  person Vikhyath Maiya    schedule 02.09.2017


Ответы (2)


Решение было простым. Только что добавлен

 display-property-name="lastName firstName"

i.e.

<input ngui-auto-complete name="doctor" 
   formControlName="doctor" 
   id="doctor" 
   [source]="doctors" 
   autocomplete="off" 
   [list-formatter]="'lastName firstName'" 
   value-formatter="lastName firstName" 
   display-property-name="lastName firstName"
   [(ngModel)] = "Doctor" 
   required>
person mixtou    schedule 21.03.2018
comment
если у меня есть этот раскрывающийся список, как я могу получить идентификатор или первичный ключ этих данных, передав int, а не объект @mixtou - person Mark Yu; 02.10.2018

Вам нужно передать [(ngModel)] внутри ввода.

Поскольку он автозаполняется и работает как раскрывающийся список, вам нужно привязать свою модель, чтобы вы могли искать данные, а также выбирать эти данные с помощью двухсторонних привязок данных.

<input ngui-auto-complete name="doctor" 
       formControlName="doctor" 
       id="doctor" 
       [source]="doctors" 
       autocomplete="off" 
       [list-formatter]="'lastName firstName'" 
       value-formatter="lastName firstName" 
       [(ngModel)] = "Doctor" 
       required>
person Mehul Solanki    schedule 24.01.2018
comment
Как это должно быть выполнено? - person Stefan; 24.01.2018
comment
Поскольку он автозаполняется и работает как раскрывающийся список, вам нужно привязать свою модель, чтобы вы могли искать данные, а также выбирать эти данные с помощью двухсторонних привязок данных. - person Mehul Solanki; 25.01.2018
comment
Можете ли вы показать, как должен быть сформирован ввод? Я задаю эти вопросы, чтобы улучшить качество вашего ответа, чтобы я мог проголосовать за него. Как правило, для ответов SO; больше информации лучше. Я думаю, что голосующий против (которым не был я) нашел ваш ответ немного минималистичным. - person Stefan; 25.01.2018
comment
В приведенном выше примере вы можете видеть, что в ngui-autocomplete вам нужен [источник], он возвращает данные, а модель определяет тип возвращаемых данных, в каком формате вы хотите получить свои данные. - person Mehul Solanki; 29.01.2018
comment
‹input ngui-auto-complete name=doctor formControlName=doctor id=doctor [source]=doctors autocomplete=off [list-formatter]='lastName firstName' value-formatter=lastName firstName [(ngModel)] = Требуется доктор › Здесь Доктор модель. - person Mehul Solanki; 29.01.2018
comment
Привет, я отредактировал ваш ответ и добавил ваши комментарии (обычно добавлять обновления в сообщение, а не в виде комментариев). Вы можете подтвердить, что это то, что вы имели в виду? - person Stefan; 29.01.2018
comment
@Стефан, да! Спасибо, приятель. - person Mehul Solanki; 30.01.2018
comment
Это реактивная форма, а не шаблон, поэтому я использую formControlName, если вы не заметили. - person mixtou; 21.03.2018