Я использую Angular 5 с Angular Material.
У меня есть список документов. Я получаю первые данные документа в форме, и они заполняются пользователем.
Я добавил поле автозаполнения, которое извлекает данные пациентов из базы данных.
После его использования я проверяю свою форму и получаю данные второго документа, но у меня также возникает проблема с полем автозаполнения:
"ERROR TypeError: Cannot read property 'subscribe' of undefined"
И соответствующая переменная равна patient.name
. Вот код, который его вызывает:
this.filteredPatients = this.myControl.valueChanges.pipe(
startWith<string | Patient>(''),
map(patient => typeof patient === 'string' ? patient : patient.name), // < error with patient.name
map(name => name ? this.filterPatient(name) : this.listPatients.slice())
);
Вот мой HTML-файл компонента:
<mat-form-field class="index-full-width">
<input
matInput
type="text"
[(ngModel)]="patientChoice"
placeholder="Patient"
aria-label="Patient"
[matAutocomplete]="autoPatient"
[formControl]="myControl"
(keyup)="getPatients($event)"
>
<mat-autocomplete (optionSelected)="selectPat()" #autoPatient="matAutocomplete" [displayWith]="displayFnPat">
<mat-option *ngFor="let patient of filteredPatients | async" [value]="patient">
<span>{{ patient.lastName }}</span>
<small>{{patient.firstName}}</small> |
<span>né(e) le {{ patient.dateNaissance }}</span> |
<small>IPP: {{patient.ipp}}</small>
</mat-option>
</mat-autocomplete>
</mat-form-field>
Файл компонента TS:
@Component({
selector: 'app-multi-index-dialog',
templateUrl: 'indexation.multiple.component.html',
styleUrls: ['indexation.multiple.component.css']
})
export class ModalMultiIndexComponent implements OnInit, AfterViewInit {
@Input()
showViewer = true;
klinckServices: KlinckServices;
listPatients: Patient[] = [];
listTasksToIndex: DataTable[] = [];
wfvd_commentaireSecretaire: '';
myControl: FormControl = new FormControl();
filteredPatients: Observable<any[]>;
patientChoice: Patient;
medecinChoice: Medecin;
taskIndex = 0;
constructor(public dialogRef: MatDialogRef<ModalMultiIndexComponent>,
@Inject(MAT_DIALOG_DATA) public data: any,
private dateAdapter: DateAdapter<Date>,
private apiService: AlfrescoApiService) {
console.log('ModalMultiIndexComponent - constructor');
this.locale = 'fr';
this.dateAdapter.setLocale('fr');
this.klinckServices = data.klinckServices;
this.listTasksToIndex.push(data.dataTable);
this.getPriorities();
this.startProcess(this.taskIndex);
}
ngOnInit() {
this.filteredPatients = this.myControl.valueChanges.pipe(
startWith<string | Patient>(''),
map(patient => typeof patient === 'string' ? patient : patient.name),
map(name => name ? this.filterPatient(name) : this.listPatients.slice())
);
}
ngAfterViewInit() {
// this.myControl.setValue('');
// this.listPatients = [];
// this.filteredPatients = new Observable<any[]>();
}
displayFnPat(patient: Patient): string | undefined {
return patient ? patient.name : undefined;
}
filterPatient(name: string) {
return this.listPatients.filter(patient =>
patient.name.toLowerCase().includes(name.toLowerCase()));
}
getPatients(event: any) {
let searchTerm = '';
searchTerm += event.target.value;
console.log(searchTerm);
if (searchTerm.length === 2) {
let success: any = {};
this.klinckServices.getPatients(searchTerm)
.then((webScriptdata) => {
success = webScriptdata;
this.listPatients = success.data.items;
console.log(this.listPatients);
},
msg => {
alert(msg);
});
}
}
selectPat(): void {
console.log(this.myControl.value.nodeRef);
console.log(this.patientChoice.nodeRef);
}
startProcess(indexElt) {
// console.log(indexElt);
// console.log(this.listTasksToIndex[0].dataRows.length);
if (indexElt < this.listTasksToIndex[0].dataRows.length) {
console.log('tâche: ' + this.listTasksToIndex[0].dataRows[indexElt][2]);
this.getDetails(this.listTasksToIndex[0].dataRows[indexElt][2]);
this.getDocNodeId(this.listTasksToIndex[0].dataRows[indexElt][2]);
} else {
this.dialogRef.close();
}
this.taskIndex = this.taskIndex + 1;
}
getDetails(taskId) {
let promiseResult: any;
this.klinckServices.getDetails(taskId)
.then((succes) => {
promiseResult = succes;
this.taskId = promiseResult.data.id;
this.documentName = promiseResult.data.description;
this.wfvd_commentaireSecretaire = promiseResult.data.properties.wfvd_commentaireSecretaire;
this.wfvd_nomService = promiseResult.data.properties.wfvd_nomService;
this.wfvd_dateDocument = promiseResult.data.properties.wfvd_dateDocument ?
new FormControl(new Date(promiseResult.data.properties.wfvd_dateDocument))
: new FormControl(new Date());
this.priorityChoice = {
id : promiseResult.data.properties.bpm_priority,
name: promiseResult.data.propertyLabels.bpm_priority
};
this.patientChoice = this.getPatientByNodeRef(promiseResult.data.properties.wfvd_patients);
this.medecinChoice = this.getMedecinByNodeRef(promiseResult.data.properties.wfvd_medecin);
this.originalPatientNodeRef = (promiseResult.data.properties.wfvd_patients !== null ?
promiseResult.data.properties.wfvd_patients : '');
this.originalMedecinNodeRef = (promiseResult.data.properties.wfvd_medecin !== null ?
promiseResult.data.properties.wfvd_medecin : '');
},
msg => {
alert(msg);
});
}
getPatientByNodeRef( patientSearch: string) {
return(this.listPatients.find( x => x.nodeRef === patientSearch));
}
getMedecinByNodeRef( medecinSearch: string) {
return(this.listMedecins.find( x => x.nodeRef === medecinSearch));
}
getDocNodeId(taskId) {
let success: any = {};
this.klinckServices.getDocNodeId(taskId)
.then((webScriptdata) => {
success = webScriptdata;
this.docNodeId = success.docNodeId;
},
msg => {
console.log(msg.error);
});
}
getPriorities() {
this.listPriorities = this.klinckServices.getPriorities();
}
getNextDoc() {
this.startProcess(this.taskIndex);
}
showPreview(event) {
this.showViewer = false;
if (event.value.entry.isFile) {
this.docNodeId = event.value.entry.id;
this.showViewer = true;
}
}
onGoBack(event: any) {
console.log('onGoBack');
this.showViewer = false;
this.docNodeId = null;
}
Метод getNextDoc()
вызывается, когда я нажимаю на кнопку формы.
Я думаю, это потому, что поле автозаполнения должно быть повторно инициализировано, но как?
Я пробовал разные методы в AfterViewInit
ловушке жизненного цикла без успеха.
UPDATE
export interface Patient {
'dateNaissance': string;
'description': string;
'displayPath': string;
'firstName': string;
'ipp': string;
'isContainer': string;
'lastName': string;
'name': string;
'nodeRef': string;
'parentType': string;
'selectable': string;
'title': string;
'type': string;
}