角嵌套模型驱动的反应式选择选项发布请求不起作用

时间:2018-09-26 08:10:49

标签: angular angular5 angular6 angular-reactive-forms angular-httpclient

对于任何HttpClient POST请求,Angular嵌套模型驱动的反应形式选择选项的正确方法是什么?我有一个简单的宁静的Web服务,其中有2个类型为运动和肌肉的对象。我正在使用Angular反应形式选择选项来发布新的运动对象。当对象肌肉嵌套在运动对象下方时,我正在使用下拉选择选项来嵌套肌肉对象。当我尝试创建/ httpclient发布一项新练习时,我得到的是肌肉的空值,而不是对象本身。以下是锻炼对象的Get示例的JSON

{
  "id": 1,
  "name": "Dumbbell curls",
  "description": "Dumbbell Stand up curls",
  "muscle": {
    "id": 1,
    "name": "Biceps",
    "exercises": [
      1
    ]
   }
  }

这是Muscle对象

{
  "id": 1,
  "name": "Biceps",
  "exercises": [
    {
      "id": 1,
      "name": "Dumbbell curls",
      "description": "Dumbbell Stand up curls",
      "muscle": 1
    }
  ]
}

当我尝试创建/发布新运动时,我的肌肉为零。

这是我的crearteExercise组件

import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { ExerciseService } from '../exercise.service';
import { Exercise } from '../exercise.model';
import { Router, ActivatedRoute } from '@angular/router';
import { FormGroup, FormControl, FormBuilder } from '@angular/forms'
import { Muscle } from '../muscle.model';
import { MuscleService } from '../muscle.service';

@Component({
selector: 'app-new-exercise',
templateUrl: './new-exercise.component.html',
styleUrls: ['./new-exercise.component.css']

}) 导出类NewExerciseComponent实现OnInit {

// @Output() saveNewExercise = new EventEmitter();

profileForm = new FormGroup({
name: new FormControl(''),
description: new FormControl(''),
muscle:new FormGroup({
  name: new FormControl('')
})

});

exercises: Exercise[];
exercise: Exercise;
muscles:Muscle[];
constructor(private everciseService: ExerciseService, 
private router: Router, 
private aR: ActivatedRoute, 
private fb: FormBuilder,
private muscleService:MuscleService) { }

ngOnInit() {
this.everciseService.getExercises()
  .subscribe(data => this.exercises = data);

this.aR.params.subscribe((params) => {
  if (params['id']) {
    this.everciseService.getExerciseById(params['id'])
      .subscribe(data => {
        console.log(data);
        this.exercise = data;
        this.profileForm = this.fb.group({
          'name': [this.exercise['name']],
          'description': [this.exercise['description']],
          'muscle':[this.exercise.muscle['name']]
        });
      })
  } else {
    this.profileForm = this.fb.group({
      'name': [null],
      'description': [null],
      'muscle':[null]
    });

  }

})

this.muscleService.getAllMuscles()
  .subscribe(data =>this.muscles= data);
}

save(exerciseId, formValues) {
debugger;
let exercise: Exercise = {
  id: undefined,
  name: formValues.name,
  description: formValues.description,
  muscle: formValues.muscle

}

if (exerciseId !== undefined) {
  this.everciseService.updateExercise(exercise, exerciseId.id)
    .subscribe(updateExercise => {
      this.router.navigate(['/exercises']);
    })
} else {
  // this.saveNewExercise.emit(exercise);

  this.everciseService.addExercise(exercise)
    .subscribe(exercise => {
      this.exercises.push(exercise);
      this.router.navigate(['/exercises']);
    });
}



}




}

这是html

<div class="container">
<h2> Add new Exercise </h2>
<form [formGroup]="profileForm" (ngSubmit)="save(exercise,profileForm.value)">
<div class="form-group">
  <label for="formGroupExampleInput">
    Exercise Name:
  </label>
  <input type="text" class="form-control" id="formGroupExampleInput" formControlName="name">

</div>
<div class="form-group">
  <label for="formGroupExampleInput">
    Description:
  </label>
  <input type="text" class="form-control" id="formGroupExampleInput" formControlName="description">

</div>


<div class="form-group">
  <label for="muscle">Select Muscle:</label>
  <select class="form-control" id="muscle" formGroupName="muscle">
    <option *ngFor="let muscle of muscles" [ngValue]="muscle.id">{{muscle.name}}</option>
  </select>
</div>
<button type="submit"   [disabled]="!profileForm.valid">Submit</button>
</form>
</div>

这是我的exerciseService

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { Exercise } from './exercise.model';
import { Observable } from 'rxjs';

@Injectable()
export class ExerciseService {

constructor(private http: HttpClient) { }

getExercises() {

return this.http.get<Exercise[]>("/api/exercise");
}

getExerciseById(id: number): Observable<Exercise> {

return this.http.get<Exercise>("/api/exercise/" + id);

}

/** POST: add a new exercise to the database */
addExercise(exercise: Exercise): Observable<Exercise> {
const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/json',
    'Authorization': 'my-auth-token'
  })
 };
return this.http.post<Exercise>("/api/exercise", exercise, httpOptions);

}
updateExercise(exercise: Exercise, id): Observable<Exercise> {
const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/json',
    'Authorization': 'my-auth-token'
  })
};
return this.http.put<Exercise>("/api/exercise/" +id, exercise,  httpOptions);

}

 deleteExercise(id){
 return this.http.delete("/api/exercise/"+id);
}


}

这是我的锻炼界面

import { Muscle } from "./muscle.model";

export interface Exercise{
id: number;
name: string;
description: string;
muscle: Muscle;
}

This is the form

1 个答案:

答案 0 :(得分:0)

<div class="form-group">
  <label for="muscle">Select Muscle:</label>
  <select class="form-control" id="muscle" formGroupName="muscle">
    <option *ngFor="let muscle of muscles" [ngValue]="muscle.id">{{muscle.name}}</option>
  </select>
</div>

这是错误的,您没有在任何地方绑定值。

<div class="form-group" formGroupName="muscle">
  <label for="muscle">Select Muscle:</label>
  <select class="form-control" id="muscle" formControl="name>
    <option *ngFor="let muscle of muscles" [ngValue]="muscle.name">{{muscle.name}}</option>
  </select>
</div>

我已将muscle.name绑定在这里,因为这是您的form结构所建议的结构:

profileForm = new FormGroup({
name: new FormControl(''),
description: new FormControl(''),
muscle:new FormGroup({ // muscle - I would put whole muscle here
  name: new FormControl('') // and ONLY name for some reasons 
})

我宁愿绑定整个muscle并让服务使用该实体所需的任何东西。这样可以使标记和代码更加清晰,并使表格结构平坦。