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
294 views
in Technique[技术] by (71.8m points)

Angular : Select Drop-Down (Mat-Select) with search-in and fill with DB. Problem with initial value

I'm currently create a request form in angular to search in a database SQL. I fill a Mat-Select with values in DB, and set the initial value at "Toutes". But since the Search in implementation, the Mat-Select is blank at page loading...

I tried to intialize the value in the html file with [(value)] set to a string in TS file. it's work only without the search'in filter.

I' intializing the array of options values in the constructor with db request, at the end of request, I call the initializing filter select.

See the HTML Code :

    <form [formGroup]="requestRessourcesForm" (ngSubmit)="onSubmit(f)" #f="ngForm">

    <div class="container-fluid">

      <div class="row d-flex align-items-center justify-content-center">

        <!-- RESSOURCE -->
        <div class="col-12  sub-section" name="ressource">

          <label class="border-lable-flt">

            <div class="container panel-style">

              <mat-form-field class="general-margin border-lable-flt">

                <mat-label class="label-section"></mat-label>

                <mat-select [(value)]="optionRessourceToutes" [placeholder]="dbRessources" [formControl]="ressourceCtrl" #ressourceSelector>

                  <mat-option>
                    <ngx-mat-select-search [formControl]="ressourceFilterCtrl" [placeholderLabel]="'Rechercher...'"
                      [noEntriesFoundLabel]="'Aucune'"></ngx-mat-select-search>
                  </mat-option>

                  <mat-option *ngFor="let ressource of filteredRessources | async" [value]="ressource.Name">
                    {{ressource.Name}}
                  </mat-option>

                </mat-select>

              </mat-form-field>
              <p>
                Selected Ressource : {{ressourceCtrl.value?.Name}}
              </p>
            </div>

            <span>Ressource</span>

          </label>

        </div>

    </div>

</form>

And the TS Code :

import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { NgForm, FormBuilder, FormGroup, FormControl, FormArray } from '@angular/forms';
import { MatSelect } from '@angular/material/select';
import { HttpClient } from '@angular/common/http';
import { ReplaySubject, Subject } from 'rxjs';
import { take, takeUntil } from 'rxjs/operators';


import { Ressource } from '../models/ressource.model';
import { environment } from '../../environments/environment';



@Component({
  selector: 'app-ressourcesplanetairesforms',
  templateUrl: './ressourcesplanetairesforms.component.html',
  styleUrls: ['./ressourcesplanetairesforms.component.scss']
})


export class RessourcesplanetairesformsComponent implements OnInit, AfterViewInit, OnDestroy {

  /*########### SQL Data ###########*/
  dbRessources: Ressource[] = [];
  public optionRessourceToutes = 'Toutes';

  requestRessourcesForm: FormGroup;

  /** control for the selected ressource */
  public ressourceCtrl: FormControl = new FormControl();

  /** control for the MatSelect filter keyword */
  public ressourceFilterCtrl: FormControl = new FormControl();

  /** list of ressources filtered by search keyword */
  public filteredRessources: ReplaySubject<Ressource[]> = new ReplaySubject<Ressource[]>(1);

  @ViewChild('ressourceSelector', { static: true }) ressourceSelect: MatSelect;

  /** Subject that emits when the component has been destroyed. */
  protected _onDestroy = new Subject<void>();


    constructor(private http: HttpClient, private formBuilder: FormBuilder) {

    
    var dbUrlPath = "./assets/db_management/";
    var dbUrlFile_Ressource;

    if (environment.production == false) {
      dbUrlFile_Ressource = "ressources_list.json";
    }
    else {
      dbUrlFile_Ressource = "ressources_list.php";
    }

    // PHP/SQL Requester : Ressource
    this.dbRessources.push(new Ressource("Toutes", null));

    this.http.get<any[]>(dbUrlPath + dbUrlFile_Ressource).subscribe(data => {
      data.forEach(element => {
        this.dbRessources.push(new Ressource(element["Name"], null));
      });

      this.InitializeRessourceSelector();
    }, error => console.error(error));

  }

  ngOnInit(): void {
  }

  ngAfterViewInit() {
  }

  ngOnDestroy() {
    this._onDestroy.next();
    this._onDestroy.complete();
  }

  onSubmit(form: NgForm) {
    console.log(form.value);

  }


  // Initialize MatSelect form
  InitializeRessourceSelector(): void {
    // Set the filters
    // set initial selection
    this.ressourceCtrl.setValue(this.dbRessources[0]);

    // load the initial ressource list
    this.filteredRessources.next(this.dbRessources.slice());

    // listen for search field value changes
    this.ressourceFilterCtrl.valueChanges
      .pipe(takeUntil(this._onDestroy))
      .subscribe(() => {
        this.filterRessources();
      });


    this.setInitialValue();
  }

  /**
   * Sets the initial value after the filteredRessources are loaded initially
   */
  protected setInitialValue() {
    this.filteredRessources
      .pipe(take(1), takeUntil(this._onDestroy))
      .subscribe(() => {
        // setting the compareWith property to a comparison function
        // triggers initializing the selection according to the initial value of
        // the form control (i.e. _initializeSelection())
        // this needs to be done after the filteredRessources are loaded initially
        // and after the mat-option elements are available
        this.ressourceSelect.compareWith = (a: Ressource, b: Ressource) => a && b && a.Name === b.Name;
      });
  }

  protected filterRessources() {
    if (!this.dbRessources) {
      return;
    }

    // get the search keyword
    let search = this.ressourceFilterCtrl.value;

    if (!search) {
      this.filteredRessources.next(this.dbRessources.slice());
      return;
    }
    else {
      search = search.toLowerCase();
    }
    // filter the Ressources
    this.filteredRessources.next(
      this.dbRessources.filter(res => res.Name.toLowerCase().indexOf(search) > -1)
    );
  }
}

Where is my mistake ?

Thanks

x


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

1 Reply

0 votes
by (71.8m points)

Ok, I found the problem, it was in the [value] of Mat-Option, I have "resource.Name" instead of "ressource"


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

1.4m articles

1.4m replys

5 comments

56.7k users

...