Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 正确地使用链接对象对支柱进行编组_Angular_Typescript_Spring Data Rest_Angular2 Forms - Fatal编程技术网

Angular 正确地使用链接对象对支柱进行编组

Angular 正确地使用链接对象对支柱进行编组,angular,typescript,spring-data-rest,angular2-forms,Angular,Typescript,Spring Data Rest,Angular2 Forms,TL;博士 在Angular 2.x+Spring Data REST+Spring Boot 1.4应用程序中,如何定义Spring可以将哪些JSON对象引用解析到域模型中 详细信息 例如,如果一本食谱包含同时创建的标签和配方,并且每个配方都引用了一个或多个标签,则表示形式可能如下所示: book: { title: 'Cook book', labels:[{ <--- array index used in labelRef below name

TL;博士

在Angular 2.x+Spring Data REST+Spring Boot 1.4应用程序中,如何定义Spring可以将哪些JSON对象引用解析到域模型中

详细信息

例如,如果一本食谱包含同时创建的
标签
配方
,并且每个
配方
都引用了一个或多个
标签
,则表示形式可能如下所示:

book: {
  title: 'Cook book',
  labels:[{            <--- array index used in labelRef below
    name: 'fruit',
    description: 'Recipe with fruit.'
  },{
    name: 'vegetable',
    description: 'Recipe with vegetables.'
  },{
    name: 'fish',
    description: 'Recipe with fish.'
  }],
  recipes:[{
    title: 'Sweet corn and onion salad',
    description: 'Simple, quick, and refreshing corn salad',
    labels: [{
      labelRef: 1      <--- using array index as reference
    }]
  }]
}
Spring数据JPA+Lombok标签中的中端表示法

@Data
@Entity
@Table(name = "LABEL")
public class Label {    
    @Id
    @Column(nullable = false)
    private Long id;

    private String name = "";
    private String description = "";

    @ManyToOne(optional=false)
    @JoinColumn(name="book_id")
    private Book book;
}
@Data
@Entity
@Table(name = "RECIPE")
public class Recipe {
    @Id
    @Column(nullable = false)
    private Long id;

    private String title = "";
    private String description = "";

    @OneToMany(cascade={CascadeType.ALL}, mappedBy="book", orphanRemoval=true)
    @Column(nullable = false)
    private List<Label> labels = new ArrayList<>();

    @ManyToOne(optional=false)
    @JoinColumn(name="book_id")
    private Book book;
}
@Data
@Entity
@Table(name = "BOOK")
public class Book {
    @Id
    @Column(nullable = false)
    private Long id;

    private String title = "";

    @OneToMany(cascade={CascadeType.ALL}, mappedBy="book", orphanRemoval=true)
    @Column(nullable = false)
    private Set<Label> labels = new HashSet<>();

    @OneToMany(cascade={CascadeType.ALL}, mappedBy="book", orphanRemoval=true)
    @Column(nullable = false)
    private List<Recipe> recipes = new ArrayList<>();

}
配方

@Data
@Entity
@Table(name = "LABEL")
public class Label {    
    @Id
    @Column(nullable = false)
    private Long id;

    private String name = "";
    private String description = "";

    @ManyToOne(optional=false)
    @JoinColumn(name="book_id")
    private Book book;
}
@Data
@Entity
@Table(name = "RECIPE")
public class Recipe {
    @Id
    @Column(nullable = false)
    private Long id;

    private String title = "";
    private String description = "";

    @OneToMany(cascade={CascadeType.ALL}, mappedBy="book", orphanRemoval=true)
    @Column(nullable = false)
    private List<Label> labels = new ArrayList<>();

    @ManyToOne(optional=false)
    @JoinColumn(name="book_id")
    private Book book;
}
@Data
@Entity
@Table(name = "BOOK")
public class Book {
    @Id
    @Column(nullable = false)
    private Long id;

    private String title = "";

    @OneToMany(cascade={CascadeType.ALL}, mappedBy="book", orphanRemoval=true)
    @Column(nullable = false)
    private Set<Label> labels = new HashSet<>();

    @OneToMany(cascade={CascadeType.ALL}, mappedBy="book", orphanRemoval=true)
    @Column(nullable = false)
    private List<Recipe> recipes = new ArrayList<>();

}
书籍
@RepositoryRestController
中正确地取消标记:

@Slf4j
@RepositoryRestController
public class BookRespositoryRestController {

    private final BookRepository bookRepository;
    private final LabelRepository labelRepository;

    @RequestMapping(method = RequestMethod.POST,value = "/books")
    public @ResponseBody PersistentEntityResource post(@RequestBody Book book,
            PersistentEntityResourceAssembler assembler) {

        Book entity = processPost(book);

        return assembler.toResource(entity);
    }
配方标签除外(因为域模型不知道
labelRef


那么,如何在Angular TypeScript应用程序中构造一个合适的
labelRef
,以便
书籍
也对每个
配方
对象中的
标签
链接进行封送处理?

TL;博士

不幸的是,它还不受支持。但是,您可以通过一些自定义代码添加支持

细节 有两个基本问题需要解决:定义JSON对象引用;对客户端JSON对象引用进行编码,对服务器端JSON对象引用进行解码

对JSON对象的引用 有许多关于“标准”JSON引用的建议(例如,请参见“”),但截至2017年,还没有“标准”

多个请求 如果可以拆分请求,请首先提交引用的对象,然后使用唯一的相对服务器端路径作为对对象的引用:

  /labels/1: {
    name: 'fruit',
    description: 'Recipe with fruit.'
  }

  /labels/2: {
    name: 'vegetable',
    description: 'Recipe with vegetables.'
  }

  /labels/3: {
    name: 'fish',
    description: 'Recipe with fish.'
  } 
然后,第二个请求使用服务器端路径:

  recipes:[{
    title: 'Sweet corn and onion salad',
    description: 'Simple, quick, and refreshing corn salad',
    labels: [{
      label: '/labels/1'
    }]
  }]
SpringDataREST不需要任何自定义代码就支持此模型(尽管您可能需要在更复杂的模型中修补任何双向指针)

单一请求 如果需要使用单个请求,请选择JSON对象引用模型并相应地对引用进行编码。在服务器端,使用自定义代码对数据进行反整理/反序列化

Spring数据REST支持。或者,数据传输对象可以执行去marhalling

我使用了JSONPath并向服务器端的数据传输对象添加了反序列化程序:

book: {
  title: 'Cook book',
  labels:[{
    name: 'fruit',
    description: 'Recipe with fruit.'
  },{
    name: 'vegetable',
    description: 'Recipe with vegetables.'
  },{
    name: 'fish',
    description: 'Recipe with fish.'
  }],
  recipes:[{
    title: 'Sweet corn and onion salad',
    description: 'Simple, quick, and refreshing corn salad',
    labels: [{
      label: '$..labels[1]'      <--- using JSONPath reference
    }]
  }]
}
书籍:{
标题:“烹饪书”,
标签:[{
名称:'水果',
描述:“水果食谱。”
},{
名称:'蔬菜',
描述:“蔬菜食谱。”
},{
名字:‘鱼’,
描述:“鱼的食谱。”
}],
食谱:[{
标题:“甜玉米洋葱沙拉”,
描述:“简单、快速、清爽的玉米沙拉”,
标签:[{

label:“$…labels[1]”尝试将JSON对象直接转换为持久性实体可能不是一个好主意;为什么不引入一个知道如何将一个转换为另一个的中间层呢?根据设计,Spring Data REST完成了大部分工作,@jornsharpe,(尽管我必须在
processPost
中修补一些对象引用,以便正确保存实体).我可以创建一个
BookJson
Java对象,它具有
labelRef
数组,并以这种方式进行修补,但SDR的目的似乎是要能够做到,如果它在Angular forms端正确编码的话……但这可能要求太高了?我能看到的唯一方法是使用自定义Jackson反序列化器或将帖子拆分为两个请求,即一个用于保存初始的book+标签。然后,您可以使用指向现有标签的正确链接发布食谱。@AlanHay--在我的示例中,将其拆分为两个请求是可行的,但在引发问题的模型中,我无法这样做。我将很快为我实施的解决方案撰写一份答案。