Dans mon angular 5, j'ai du matAutocomplete, mais je veux forcer la sélection d'une seule des suggestions, donc je suis cette approche: stackblitz mais pour une raison quelconque dans un cas, j'ai un problème:
Impossible de lire la propriété 'panelClosingActions' de undefined sur CustomerDetailComponent.countryClosingActions (customer-detail.component.ts: 199) sur CustomerDetailComponent.ngAfterViewInit
J'ai plusieurs matAutocomplete mais seulement celui-ci a des problèmes. (les informations sur cette méthode sont ici github
html
<mat-form-field>
<input matInput #nation placeholder="{{'customer.detail.labels.country'
| translate }}" required [matAutocomplete]="tdAuto" name="country"
#count="ngModel" [(ngModel)]="selected.country"
(ngModelChange)="searchCountry($event)">
<mat-autocomplete #tdAuto="matAutocomplete" [displayWith]="displayFn">
<mat-option (onSelectionChange)="setCountry(country)" *ngFor="let country of countries" [value]="country">
<div class="row">
<img src="assets/img/flags24/{{country.alpha2Code | lowercase}}.png" />
<span>{{country.name}} ({{country.alpha2Code}})</span>
</div>
</mat-option>
</mat-autocomplete>
</mat-form-field>
composant
@ViewChild('nation', { read: MatAutocompleteTrigger }) trigger: MatAutocompleteTrigger;
subscription: Subscription;
ngAfterViewInit() {
this.countryClosingActions();
}
private countryClosingActions(): void {
if (this.subscription && !this.subscription.closed) {
this.subscription.unsubscribe();
}
this.subscription = this.trigger.panelClosingActions
.subscribe(e => {
console.log('closing')
if (!e || !e.source) {
this.selected.country = null;
this.selfCountry = null;
}
},
err => this.countryClosingActions(),
() => this.countryClosingActions());
}
En utilisant l'événement flou et l'événement de sortie matAutocomplete (optionSelected), nous pouvons forcer l'utilisateur à sélectionner l'option.
<mat-form-field class="example-full-width">
<input type="text" placeholder="Country*" matInput formControlName="country" [matAutocomplete]="countryAutoList" (blur)="checkCountry()">
<mat-autocomplete autoActiveFirstOption #countryAutoList="matAutocomplete" (optionSelected)="countryClick($event)">
<mat-option *ngFor="let item of countryList" [value]="item.Name">{{item.Name}}</mat-option>
</mat-autocomplete>
</mat-form-field>
fonctions du fichier ts
countryClick(event: any) {
this.selectedCountry = event.option.value;
}
checkCountry() {
if (!this.selectedCountry || this.selectedCountry !== this.signatureFormGroup.controls['country'].value) {
this.signatureFormGroup.controls['country'].setValue(null);
this.selectedCountry = '';
}
}
J'ai trouvé ceci utile:
private subscribeToClosingActions(): void {
if (this.subscription && !this.subscription.closed) {
this.subscription.unsubscribe();
}
this.subscription = this.autoCompleteTrigger.panelClosingActions
.subscribe((e) => {
if (!e || !e.source) {
const selected = this.matAutocomplete.options
.map(option => option.value)
.find(option => option === this.formControl.value);
if (selected == null) {
this.formControl.setValue(null);
}
}
},
err => this.subscribeToClosingActions(),
() => this.subscribeToClosingActions());
}
L'exemple qu'ils donnent sur le site utilise l'approche Formulaire réactif, mais dans votre cas, vous semblez pencher vers l'approche pilotée par modèle, mais vous n'utilisez pas de période de formulaire.
Vous pouvez donc accéder directement à l'élément dom comme vous le faites actuellement.
Créez une référence locale à votre entrée, peut-être appelez-la autoComplInput
Dans votre fichier de composant, vous voudrez importer ElementRef
et Afficher Child
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
Dans votre composant, importez ViewChild et déclarez-le comme un type ElementRef
@ViewChild('autoComplInput') autoComplInput: ElementRef;
Ensuite, à un moment de l'initialisation, attribuez simplement la valeur de l'élément référencé
ngOnInit() {
this.autoComplInput.nativeElement.value = this.countries[0];
}
Démo basée sur Angular Exemple de Material 2, puisque vous n'avez pas fourni toutes les informations nécessaires.
Dans votre html
<mat-form-field>
<input matInput
placeholder="{{'country'}}"
required
[matAutocomplete]="tdAuto"
name="country"
#autoComplInput
(ngModelChange)="searchCountry($event)">
<mat-autocomplete #tdAuto="matAutocomplete" >
<mat-option *ngFor="let country of countries" [value]="country">
<div class="row">
<span>{{country}} </span>
</div>
</mat-option>
</mat-autocomplete>
</mat-form-field>
Dans votre composant
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
@Component({
selector: '<...>',
templateUrl: '<...>',
styleUrls: ['<...>'],
})
export class <...> implements OnInit {
@ViewChild('autoComplInput') autoComplInput: ElementRef;
countries = [
'Alabama',
'Alaska',
'Arizona',
'Arkansas',
'California',
'Colorado',
'Connecticut',
'Delaware',
'Florida',
'Georgia',
'Hawaii',
'Idaho',
'Illinois',
'Indiana',
'Iowa',
'Kansas',
'Kentucky',
'Louisiana',
'Maine',
'Maryland',
'Massachusetts',
'Michigan',
'Minnesota',
'Mississippi',
'Missouri',
'Montana',
'Nebraska',
'Nevada',
'New Hampshire',
'New Jersey',
'New Mexico',
'New York',
'North Carolina',
'North Dakota',
'Ohio',
'Oklahoma',
'Oregon',
'Pennsylvania',
'Rhode Island',
'South Carolina',
'South Dakota',
'Tennessee',
'Texas',
'Utah',
'Vermont',
'Virginia',
'Washington',
'West Virginia',
'Wisconsin',
'Wyoming',
];
constructor( ) {}
ngOnInit() {
this.autoComplInput.nativeElement.value = this.countries[0];
}
}