如何根据提供的JSON数据使用Angular构建嵌套的反应性形式结构

发布于 2025-01-25 16:46:04 字数 1064 浏览 2 评论 0原文

我是新来的角。以下是我从postman中获得的JSON数据。我正在尝试使用此形式构建表格

  data = {
    headline: [
      {
        language: 'en',
        headlineText: 'example headline',
      },
    ],
    bodyText: [
      {
        language: 'en',
        bodyText: 'example bodytext',
      },
    ],
    location: {
      name: 'mkontheway',
      openingHours: [
        {
          day: 'Mon-frd',
          timing: '10.00PM-9AM',
        },
      ],
      address: {
        postCode: 'test',
        country: 'test',
      },
    },
  };

,但是在这里,正时字段重复了2次。由于嵌套形式的结构,我无法正确控制这两个字段。请有人向我建议我在角度建立复杂的嵌套形式结构的解决方案。

提前致谢。

这是堆栈Blitz链接

角嵌套形式

这里有嵌套的形式组,形式阵列在那里。请建议我如何使用角反应式形式实现此嵌套形式的实现,

我从此堆栈闪电战中获取了参考 >

I'm new to angular. Below is the JSON data I'm getting from GET call in postman. I'm trying to build the form using this

  data = {
    headline: [
      {
        language: 'en',
        headlineText: 'example headline',
      },
    ],
    bodyText: [
      {
        language: 'en',
        bodyText: 'example bodytext',
      },
    ],
    location: {
      name: 'mkontheway',
      openingHours: [
        {
          day: 'Mon-frd',
          timing: '10.00PM-9AM',
        },
      ],
      address: {
        postCode: 'test',
        country: 'test',
      },
    },
  };

But here Day and Timing fields are repeating 2 times. I'm not able to get the control of these two fields correctly because of nested form structure. Please someone suggest me the solution to build a complex nested form structure in angular.

Thanks in advance.

Here is the stack blitz link

Angular Nested Form

Here there are nested form groups and form arrays are there. Please suggest me how to achieve this nested form implementation using angular reactive forms

I took the reference from this stack blitz example
Reference Stack blitz

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

酒几许 2025-02-01 16:46:04

您只需要在该位置的开放室中创建空的 formarray,

   this.createAppForm = this.fb.group({
      ...
      location: this.fb.group({
        name: ['', Validators.required],
        openingHours: this.fb.array([]), //<--this is an "empty" formAray
        address: this.fb.group({
           ...
        }),
      }),
    });

但是(始终在那里)看到您的代码,您有许多重复来创建不同的formgroup。重复代码使我们尽早遇到麻烦。

因此,我们将创建返回组合您的FormGroup的FormGroup的函数,

以想象您有一些喜欢

  setHeadLine(data: any = null) {
    data = data || { language: null, headlineText: null };
    return this.fb.group({
      headlineText: data.headlineText,
      language: data.language,
    });
  }

  setBodyText(data: any = null) {
    data = data || { bodyText: null, language: null };
    return this.fb.group({
      bodyText: data.bodyText,
      language: data.language,
    });
  }

  setAddress(data: any = null) {
    data = data || { postCode: null, country: null };
    return this.fb.group({
      postCode: [data.postCode, Validators.required],
      country: [data.country, Validators.required],
    });
  }

  setOpeningHour(data: any = null) {
    data = data || { day: null, timing: null };
    return this.fb.group({
      day: [data.day, Validators.required],
      timing: [data.timing, Validators.required],
    });
  }

  setLocation(data: any = null) {
    console.log(data);
    data = data || { name: null, openingHours: null, address: null };
    return this.fb.group({
      name: [data.name, Validators.required],
      openingHours: this.fb.array(
        data.openingHours
          ? data.openingHours.map((x) => this.setOpeningHour(x))
          : []
      ),
      address: this.setAddress(data.address),
    });
  }

查看对函数setAddress的“ setLocation”如何创建FormGroup Adress以及OpenTHOURS是this.fb.array。如果data.openingHours是一个数组,请在formgroup数组中转换对象数组并创建formArray,否则返回空数组,

最后您创建一个函数,以此方式返回您的FormGroup

  setFormGroup(data: any = null) {
    data = data || { headline: null, bodyText: null, location: null };
    return this.fb.group({
      headline: this.fb.array(
        data.headline ? data.headline.map((x) => this.setHeadLine(x)) : []
      ),
      bodyText: this.fb.array(
        data.bodyText ? data.bodyText.map((x) => this.setBodyText(x)) : []
      ),
      location: this.setLocation(data.location),
    });
  }

i,以此方式返回您不重复代码。在构造函数中,您可以编写

 this.createAppForm = this.setFormGroup(this.data);

,当您添加formGroup时,请简单地调用函数:

  addHeadline() {
    this.getHeadlineFormData().push(this.setHeadLine())
  }

  addBodyText() {
    this.getBodyTextFormData().push(this.setBodyText())
  }

  addOpeningHours() {
    this.getopeningHoursFormData().push(this.setOpeningHour())
  }

嗯,(这只是一个建议)我认为使用“ Getter”代码变得更加清晰,因此,如果您替换,

//replace
  getHeadlineFormData() {
    return <FormArray>this.createAppForm.get('headline');
  }
//by 
  get headlineFormData() {
    return <FormArray>this.createAppForm.get('headline');
  }

//replace
  getBodyTextFormData() {
    return <FormArray>this.createAppForm.get('bodyText');
  }
//by
  get bodyTextFormData() {
    return <FormArray>this.createAppForm.get('bodyText');
  }

//replace
  getLocationFormData() {
    return <FormArray>this.createAppForm.get('location');
  }
//by
  get locationFormData() {
    return <FormArray>this.createAppForm.get('location');
  }

//and replace
  getopeningHoursFormData() {
    return <FormArray>this.createAppForm.get('location')?.get('openingHours');
  }
//by
  get openingHoursFormData() {
    return <FormArray>this.createAppForm.get('location')?.get('openingHours');
  }

则可以使用> this.headlineformdata而不是this.getheadlineformdata() - 请参见使用getter您不编写父母。在html 中,headlineformdata.controls而不是getheadlineformdata()。controls - 请参见使用“ getter”您不编写括号。

您的

You only need create an empty formArray in openingHours in the location

   this.createAppForm = this.fb.group({
      ...
      location: this.fb.group({
        name: ['', Validators.required],
        openingHours: this.fb.array([]), //<--this is an "empty" formAray
        address: this.fb.group({
           ...
        }),
      }),
    });

But (always there're a but) seeing your code you has many repetitions to create the differents FormGroups. And repeat code makes we enter in trouble early.

So we are going to create functions that return the formGroups that compouned your FormGroup

Imagine you has some like

  setHeadLine(data: any = null) {
    data = data || { language: null, headlineText: null };
    return this.fb.group({
      headlineText: data.headlineText,
      language: data.language,
    });
  }

  setBodyText(data: any = null) {
    data = data || { bodyText: null, language: null };
    return this.fb.group({
      bodyText: data.bodyText,
      language: data.language,
    });
  }

  setAddress(data: any = null) {
    data = data || { postCode: null, country: null };
    return this.fb.group({
      postCode: [data.postCode, Validators.required],
      country: [data.country, Validators.required],
    });
  }

  setOpeningHour(data: any = null) {
    data = data || { day: null, timing: null };
    return this.fb.group({
      day: [data.day, Validators.required],
      timing: [data.timing, Validators.required],
    });
  }

  setLocation(data: any = null) {
    console.log(data);
    data = data || { name: null, openingHours: null, address: null };
    return this.fb.group({
      name: [data.name, Validators.required],
      openingHours: this.fb.array(
        data.openingHours
          ? data.openingHours.map((x) => this.setOpeningHour(x))
          : []
      ),
      address: this.setAddress(data.address),
    });
  }

See how the "setLocation" call to the function setAddress to create the formGroup adress and how openingHours is a this.fb.array. If data.openingHours is an array, convert the array of objects in an array of formGroups and create the formArray, else return an empty array

Finally you create a function that return your formGroup

  setFormGroup(data: any = null) {
    data = data || { headline: null, bodyText: null, location: null };
    return this.fb.group({
      headline: this.fb.array(
        data.headline ? data.headline.map((x) => this.setHeadLine(x)) : []
      ),
      bodyText: this.fb.array(
        data.bodyText ? data.bodyText.map((x) => this.setBodyText(x)) : []
      ),
      location: this.setLocation(data.location),
    });
  }

I this way you not repeat code. In the constructor you can write

 this.createAppForm = this.setFormGroup(this.data);

And when you add a FormGroup simply call the functions:

  addHeadline() {
    this.getHeadlineFormData().push(this.setHeadLine())
  }

  addBodyText() {
    this.getBodyTextFormData().push(this.setBodyText())
  }

  addOpeningHours() {
    this.getopeningHoursFormData().push(this.setOpeningHour())
  }

Well, (this last is only a suggestion) I think that the code becomes more clear using "getter", so if you replace

//replace
  getHeadlineFormData() {
    return <FormArray>this.createAppForm.get('headline');
  }
//by 
  get headlineFormData() {
    return <FormArray>this.createAppForm.get('headline');
  }

//replace
  getBodyTextFormData() {
    return <FormArray>this.createAppForm.get('bodyText');
  }
//by
  get bodyTextFormData() {
    return <FormArray>this.createAppForm.get('bodyText');
  }

//replace
  getLocationFormData() {
    return <FormArray>this.createAppForm.get('location');
  }
//by
  get locationFormData() {
    return <FormArray>this.createAppForm.get('location');
  }

//and replace
  getopeningHoursFormData() {
    return <FormArray>this.createAppForm.get('location')?.get('openingHours');
  }
//by
  get openingHoursFormData() {
    return <FormArray>this.createAppForm.get('location')?.get('openingHours');
  }

You can use this.headlineFormData instead this.getHeadlineFormData() -see that using a getter you don't write parentesis. and in html headlineFormData.controls instead getHeadlineFormData().controls -again see that using a "getter" you don't write parenthesis.

Your forked stackbliz

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文