ERROR TypeError:尝试使用formArray时无法读取未定义的属性'map'

问题描述 投票:0回答:1

我正在尝试在Mat对话框中显示添加播放列表,该播放列表使用(formArray)像这样在列表中包含歌曲:enter image description here

但我不断得到:

错误TypeError:无法读取未定义的属性'map'

和我的对话是这样的:enter image description here

这是我的代码:

我的Dialog.component.html

<h1 mat-dialog-title>Create New Playlist
</h1>
<form [formGroup]='form'>
<div>

  <div mat-dialog-content>


      <mat-form-field class="input-width" appearance="standard">
        <mat-label>Playlist name</mat-label>
        <input  matInput placeholder="" required formControlName="name"  [(ngModel)]="data.name">

      </mat-form-field>
      <mat-form-field class="input-width" appearance="standard">
        <mat-label>Description</mat-label>
        <input  matInput placeholder="" required formControlName="description" [(ngModel)]="data.description" >

      </mat-form-field>
        <mat-dialog-actions class="action-buttons">
    <button mat-raised-button  color="warn" (click)="close()" >Cancel </button>
  <button mat-raised-button color="primary"  [disabled] = "form.invalid" (click)="onSubmit()" [mat-dialog-close]="data">Submit</button>

  </mat-dialog-actions>      
  <div formArrayName="songs" *ngIf="this.form">
    <div *ngFor = "let song of songsform().controls; let i = index">
      <div class="song-input-wrapper" [formGroupName]="i">
        <mat-form-field  appearance="standard">
          <mat-label>Song Title</mat-label>
          <input  matInput placeholder="" required formControlName="title">

        </mat-form-field>
        <mat-form-field  appearance="standard">
          <mat-label>Artist</mat-label>
          <input matInput placeholder="" required formControlName="artist">

        </mat-form-field>
        <mat-form-field appearance="standard">
          <mat-label>Duration</mat-label>
          <input matInput type="number" required  formControlName="duration">
          <span matSuffix>minutes</span>
        </mat-form-field>
          <button mat-icon-button color="primary" (click)="addSong()">
            <mat-icon>add_circle</mat-icon>
          </button>
          <button
          *ngIf="songsform().controls.length > 1"
          mat-icon-button
          color="warn"
          (click)="removeSong(i)"
        >
          <mat-icon>remove_circle</mat-icon>
        </button>


      </div>
    </div>
  </div>




</div>



  </div>

</form>

和我的dialog.componenet.ts:

export class DialogComponent implements OnInit {

  description:string;
  songs: FormArray;

  constructor(public service: PlaylistService,public dialogRef: MatDialogRef<DialogComponent>, private formBuilder: FormBuilder, @Inject(MAT_DIALOG_DATA) public data: Playlist  ) 
   { 
   }
   form : FormGroup 

  songsform() :FormArray { 
    return this.form.get('songs') as FormArray ;
  }

  ngOnInit(): void {

       if (!this.data) {
      this.form = this.formBuilder.group({
        name: [null, Validators.required],
        description: [null, Validators.required],
        songs: this.formBuilder.array([ this.createSong() ]),
      });
    } else {
      this.form = this.formBuilder.group({
        name: [this.data.name, Validators.required],
        description: [this.data.description, Validators.required],
        songs: this.formBuilder.array(
          this.data.songs.map(song => this.formBuilder.group({
            title: [song.title, Validators.required],
            artist: [song.artist, Validators.required],
            duration: [song.duration, Validators.compose([Validators.required, Validators.min(0)])],
          }))
        ),
      })}

  }
  close() {
    this.dialogRef.close();
}

createSong(): FormGroup {
  return this.formBuilder.group({
    title: [null, Validators.required],
    artist: [null, Validators.required],
    duration: [null, Validators.compose([Validators.required, Validators.min(0)])],
  });
}
addSong(): void {
  this.songs.push(this.createSong());
}
removeSong(index: number): void {
  if (this.songs.controls.length > 1) {
    this.songs.removeAt(index);
  }
}
  onSubmit(){

      this.dialogRef.close(this.form.value);

  }  
  }

最后是打开对话框和播放列表类所在的组件:

export interface Playlist {
  name: string;
  totalDuration: number;
  totalSongs: number;
  description: string;
  songs: Song[];
}

export interface Song {
  title: string;
  artist: string;
  duration: number;
}
@Component({
  selector: 'app-playlist',
  templateUrl: './playlist.component.html',
  styleUrls: ['./playlist.component.css']
})

export class PlaylistComponent implements OnInit {


  constructor(public dialog: MatDialog,public service: PlaylistService) { }

  ngOnInit(): void {
  }



  playlists: Playlist[] = [
    {
      name: 'Kopikustik',
      totalDuration: 5,
      totalSongs: 2,
      description: 'More than a coffee, this is all of your favorite accoustic songs.',
      songs: [
        {
          title: 'Cigarettes of ours',
          artist: 'Ardhito Pramono',
          duration: 3
        },
        {
          title: 'Walking Back Home',
          artist: 'Vira Talisa',
          duration: 2
        },
      ]
    },
    {
      name: 'Anime Hits',
      totalDuration: 13,
      totalSongs: 3,
      description: 'Listen to your favorite Anime songs, all in one playlist.',
      songs: [
        {
          title: 'Renai Circulation',
          artist: 'Kana Hanazawa',
          duration: 4
        },
        {
          title: 'Platinum Disco',
          artist: 'Tsukihi Phoenix',
          duration: 4
        },
        {
          title: 'Silhouette',
          artist: 'KANA-BOON',
          duration: 5
        },
      ]
    }
  ];
  name:String
  @Input() data: Playlist
  openDialog(): void {
    const dialogConfig = new MatDialogConfig();
    dialogConfig.autoFocus = false;
    const dialogRef = this.dialog.open(DialogComponent, {

      width: '900px',
      data: {
        name : this.name,
      /*  description:'',
        title:'',
        artist:'',
        duration:0*/
      }
    });

    dialogRef.afterClosed().subscribe(result => {
      console.log('The dialog was closed');
      if (result) {
        this.name = result.name;
        alert("name is :"+ this.name)
        }
    });
  }

  deletePlaylist(i)
  {
    this.playlists.splice(i, 1);
  }

}

我不明白他为什么有问题this.data.songs.map(song => this.formBuilder.group())

[如果有人熟悉或可以看到我缺少的内容,请帮助我

arrays angular dictionary dialog formarray
1个回答
0
投票

songs未初始化为正在注入DialogComponent的数据。您可以在构造对话框数据时将其初始化为空数组:

© www.soinside.com 2019 - 2024. All rights reserved.