web-dev-qa-db-fra.com

Angular Sélection de la force de saisie semi-automatique du matériau

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());
  }
10
Alessandro

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 = '';
  }
}
7
Amit kumar

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());
}
1
hbthanki

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];
  }


}
0
Iancovici