Angular 4更新嵌套字段

时间:2017-08-07 10:55:32

标签: angular rest spring-data-rest hateoas spring-hateoas

使用@angular/http method http.put()更新模型时遇到问题。

问题在于我根本无法更新位置。我可以成功更新任何其他字段,并可以在使用POST创建时设置任何位置。

我的角度版本是“^ 4.3.3”

在java中,我的模型看起来像

public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;

    String name;

    String email;

    String phone;

    Date birthDay;

    @JsonBackReference
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "position_id")
    Position position;
}

投影:

public interface EmployeeProjection {

    Long getId();

    String getName();

    String getEmail();

    String getPhone();

    Date getBirthDay();

    @Value("#{target.position.name}")
    String getPosition();
}

和职位课程:

public class Position {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;

    String name;
}

在角度模板位置:

<md-select mdInput placeholder="Position"
           [(ngModel)]="newEmployee.position">
  <md-option *ngFor="let position of positions | async" [value]="position.name">{{ position.name }}
   </md-option>
</md-select>

我在组件中的更新方法:

update() {
    let positionName = this.employee.position;
    this.positionService.findByName(positionName).subscribe(position => {
      this.employee.position = position._links.self.href;
      this.employeeService.update(this.employee);
      this.employee.position = positionName;
      this.employeeService.localStorageService.set('employee', this.employee);
    });
  }

在服务中:

update(employee: Employee) {
    this.http.put(employee._links.self.href, employee)
      .map((resp: Response) => resp.json())
      .subscribe(() => {
        this.getAll();
      });
    return employee;
  }

在Chrome请求中:

{
  "name": "Nikolai Morgan",
  "id": 1,
  "position": "http://localhost:9080/api/positions/5",
  "birthDay": "1986-07-01",
  "email": "NikolaiMorgan@gmail.com",
  "phone": "+380840713229",
  "_links": {
    "self": {
      "href": "http://localhost:9080/api/employees/1"
    },
    "employee": {
      "href": "http://localhost:9080/api/employees/1{?projection}",
      "templated": true
    },
    "position": {
      "href": "http://localhost:9080/api/employees/1/position"
    }
  }
}

但响应和预览不包含字段位置:

{
  "id" : 1,
  "name" : "Nikolai Morgan",
  "email" : "NikolaiMorgan@gmail.com",
  "phone" : "+380840713229",
  "birthDay" : "1986-07-01",
  "_links" : {
    "self" : {
      "href" : "http://localhost:9080/api/employees/1"
    },
    "employee" : {
      "href" : "http://localhost:9080/api/employees/1{?projection}",
      "templated" : true
    },
    "position" : {
      "href" : "http://localhost:9080/api/employees/1/position"
    }
  }
}

1 个答案:

答案 0 :(得分:1)

要更新引用另一个实体的实体,在Spring Data REST中,您必须使用指向此实体的链接。例如:

@Entity
class Employee {
    //...

    String name;

    @ManyToOne
    Position position;   

    //...
}

@Entity
class Position {
    //...

    String name;

    //...
}

interface EmployeeRepo extends JpaRepository<Employee, Long> {}
interface PositionRepo extends JpaRepository<Position, Long> {}

首先我们添加一个位置:

POST http://localhost:9080/api/positions

{
    "name": "position1"
}

得到这样的回复:

{
    "name": "position1",
    "_links" : {
        "self" : {
          "href" : "http://localhost:9080/api/positions/1"
        },
        "position" : {
          "href" : "http://localhost:9080/api/positions/1"
        }
    }
}

然后添加一名员工:

POST http://localhost:9080/api/employees

{
    "name": "employee1",
    "employee": "http://localhost:9080/api/positions/1"
}

然后得到回复:

{
  "name" : "employee1",
  "_links" : {
    "self" : {
      "href" : "http://localhost:9080/api/employees/1"
    },
    "employee" : {
      "href" : "http://localhost:9080/api/employees/1",
    },
    "position" : {
      "href" : "http://localhost:9080/api/employees/1/position"
    }
  }
}

因此,如果我们需要更新职位,我们会创建一个新职位,然后将员工PUT:

PUT http://localhost:9080/api/employees/1

{
    "name": "employee1", 
    "position": "http://localhost:9080/api/positions/2"
}

甚至修补它:

PATCH http://localhost:9080/api/employees/1

{
    "position": "http://localhost:9080/api/positions/2"
}