How to populate mat-select with angular material?

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-06 03:37:31

问题


Hey I'm trying to use angular material and I'm having an issue. In my project I get movies details such as title,year,genre and so on. I'm trying to make an edit popup and when I got to the genre edit I got a little problem. how can I populate the select line with genres the movie already has?

lets say for example I want the default value to be: "Action,Comedy".

my html:

<mat-select placeholder="Genre" [formControl]="genre" multiple>
    <mat-option *ngFor="let genre of genresList" value="Action,Comedy" >{{genre}}</mat-option>
  </mat-select>
  <mat-error *ngIf="genre.hasError('required')">
      Title is <strong>required</strong>
    </mat-error>
</mat-form-field>

component:

export class MyDialogComponent implements OnInit {

  selectedMovie: MyMovie;


  title:FormControl;
  year:FormControl;
  runtime:FormControl;
  genre:FormControl;
  director:FormControl;


  genresList: string[] = ['Action', 'Comedy', 'Horror', 'Fantasy', 'Drama', 'Romance'];

  constructor(private dataService: DataService) {
    this.selectedMovie = dataService.selectedMovie;

    this.title = new FormControl(this.selectedMovie.Title, [
      Validators.required
    ]);
    this.year = new FormControl(this.selectedMovie.Year, [
      Validators.required
    ]);
    this.runtime = new FormControl(this.selectedMovie.Runtime, [
      Validators.required
    ]);
    this.genre = new FormControl("this.selectedMovie.Genre", [
      Validators.required
    ]);
    this.director = new FormControl(this.selectedMovie.Director, [
      Validators.required
    ]);


  }

Appreciate any help! thanks

update:

this.dataService.getMovie(this.moviesToLoad[i]).subscribe(res => {

        this.movie = {
           id: this.id,
           Title: res.Title,
           Year: res.Year,
           Runtime: res.Runtime,
           Genre: res.Genre.split(","),
           Director: res.Director
          }

res is just string which im trying to change to array, something wrong over since i get only the first element of the array in the default mat-select.. how can i fix that?


回答1:


You should be creating a FormGroup instead of individual FormControls.

Genre in your Movie is a string but the multiple select list will need an array of string to show multiple values. Also, looks like there's a space between the genres(Action, Crime) which when trimmed will create an extra starting space in Crime. To fix that, you'll need to split by , and then apply map on the array elements to remove the extra space by using trim. This will be done by this like:

genre: [this.selectedMovie.Genre.split(',').map(genre => genre.trim()), [Validators.required]],

So your code will look something like:

import { FormGroup, FormBuilder, Validators } from '@angular/forms';

...
selectedMovie: MyMovie;
movieForm: FormGroup;
genresList = ['Action', 'Comedy', 'Horror', 'Fantasy', 'Drama', 'Romance'];

constructor(
  private fb: FormBuilder,
  private dataService: DataService
) {}

ngOnInit() {

  this.dataService.getMovie('anyIndexHere')
    .subscribe(selectedMovie => {

      this.selectedMovie = {
        id: 'Some ID',
        ...selectedMovie
      }

      this.movieForm = this.fb.group({
        title: [this.selectedMovie.Title, [Validators.required]],
        year: [this.selectedMovie.Year, [Validators.required]],
        runtime: [this.selectedMovie.Runtime, [Validators.required]],
        genre: [this.selectedMovie.Genre.split(',').map(genre => genre.trim()), [Validators.required]],
        director: [this.selectedMovie.Director, [Validators.required]],
      });

    });
}

Since we're already assigning the default value to the genre FormControl, it will be selected by default in your template.

So in your template, you'll now be using the attribute binding syntax([formGroup]="movieForm") to bind to the form. And then for the mat-select since you'll be specifying the formControlName as genre which is the FormControl for the Genre field, you'll see the Genre's selected by default.

So your template would look something like:

<form [formGroup]="movieForm">
  ...
  <mat-form-field>
    <mat-select placeholder="Movie Genre" formControlName="genre" multiple>
      <mat-option *ngFor="let genre of genresList" [value]="genre">
        {{genre}}
      </mat-option>
    </mat-select>
  </mat-form-field>
  ...
</form>

Here's a Sample StackBlitz for your ref.



来源:https://stackoverflow.com/questions/52672346/how-to-populate-mat-select-with-angular-material

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!