【问题标题】:Angular 4 update nested fieldAngular 4更新嵌套字段
【发布时间】:2018-01-14 15:49:29
【问题描述】:

在使用 @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"
    }
  }
}

【问题讨论】:

  • 那么“问题是什么?”,哈姆雷特? ;)
  • 如何更新模型中嵌套字段的值?
  • 看我的回答...

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


【解决方案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"
}

【讨论】:

  • 感谢您的解决方案,我选择了带有 PATCH 的变体。如果您阐明如何使用现有职位和员工使用 PUT 进行更新,我也将不胜感激
  • 在我的代码中,您可以看到我也设置了位置链接,但这并没有触发。我想了解我的错误在哪里
  • Что ты имеешь в виду под “没有开火”? В 响应,который ты привел,ссылка на position присутствует:http://localhost:9080/api/employees/1/position。 Или новая позиция в БД не сохраняется? Или что?..
  • Да,обновляютсявсеполя,кромепозиции,онапростоигнорится,хотявсеттеронаприходит,новрепозиторииприсохраненииужестароезначение跨度>
  • Подключи логировнаие - посмотри, какие реально запросы идут в базу。 И еще, не работает только PUT или PATCH тоже?..
猜你喜欢
  • 1970-01-01
  • 2015-03-05
  • 1970-01-01
  • 2017-03-25
  • 2015-10-22
  • 1970-01-01
  • 2021-08-29
  • 2014-07-07
  • 2021-09-19
相关资源
最近更新 更多