Как создать массив форм в формате дерева в angular14?

Я прикрепил ссылку на свой код. Я попытался создать массив формы динамического вложенного дерева. Но я не знаю, как создать. Я новичок в угловых рамках. https://stackblitz.com/edit/angular-vytk36?file=src/index.html

Разместите здесь свой код.

possum 19.04.2023 15:45

Это много кода. Было бы лучше добавить к вопросу ту часть, которая вызывает у вас затруднения.

Nigel Peck 19.04.2023 16:53

Вы хотите создать FormArray из FormAray, посмотрите это ТАК или это другое

Eliseo 19.04.2023 16:53

@Eliseo Я пытаюсь преобразовать массив в формат дерева структур данных. Можно ли создать массив угловых форм?

Arunkumar 20.04.2023 07:49

Сколько «глубин» у вашей структуры, одна, две, три, неопределенные? Можете ли вы привести пример .json, которым вы хотите управлять?

Eliseo 20.04.2023 08:09

@Eliseo { "меню": [ { "nestedmenu": [ { "nestedmenu": [ {} ] } ] } ] } уровень без конца... Можно создать?

Arunkumar 20.04.2023 15:30

@Арункумар, конечно! (невозможно ничего), но это немного сложно. Я только что добавил ответ. надеюсь смогу помочь

Eliseo 21.04.2023 08:44

@Eliseo Я пробовал этот формат { "меню": [ { "nestedmenu": [ { "nestedmenu": [ { "nestedmenu": [], "submenu": [] } ], "submenu": [] } ] , "submenu": [] } ] } Как добавить подменю. Пожалуйста, помогите мне.

Arunkumar 24.04.2023 11:49

Я пытался, но у меня возникла проблема. stackblitz.com/edit/angular-pezmpp?file=src/form.component.t‌​s

Arunkumar 24.04.2023 15:03
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
9
121
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Всегда у нас есть "бесконечный уровень" - это работа над "рекурсивным компонентом"

Рекурсивный компонент — это только компонент, который вызывает сам себя (см., например, это ТАК)

Управлять дочерним компонентом, который управляет formGroup от родителя, не очень просто. Мы можем использовать viewProviders или передать FormGroup во входных данных (см. это еще один SO)

Мы собираемся выбрать передать formGroup. Но поскольку наш компонент является рекурсивным компонентом, который нам нужен в группе форм, поэтому я использую другой ввод, который является «именем» группы форм. (помните, что наши formArrays — это formArrays formGroups. Нам нужно «достучаться» до formGroup

Пух...!

Прежде чем мы собираемся определить функцию для создания formGroup. Мы экспортируем его, потому что одна и та же функция может использоваться родителем и компонентом.

export function setNestedMenu(data:any=null){
  data=data || {name: "",displayname: "",id: "",nestedMenu: []}
  return new FormGroup({
      name:new FormControl(data.name),
      displayName:new FormControl(data.name),
      id:new FormControl(data.name),
      nestedMenu:new FormArray(data.nestedMenu.map((x:any)=>this.setNestedMenu(x)))
  })
}

ПРИМЕЧАНИЕ. Я использую camelCase, чтобы придать значение «свойствам».

Компонент

@Component({
  selector: 'form-component',
  standalone: true,
  imports: [CommonModule, FormsModule, ReactiveFormsModule],
  template: `
  <div [style.margin-left.px] = "index*10" *ngIf = "formGroup" [formGroup] = "formGroup" >
  <div formArrayName = "nestedMenu">
     <button (click) = "addMenu()">add</button>
     <div *ngFor = "let group of menuArray?.controls;let i=index" 
                                          [formGroupName] = "i">
       <input formControlName = "id"/>
       <input formControlName = "name"/>
       <input formControlName = "displayName"/>
       <button (click) = "removeMenu(i)">remove</button>
       <button (click) = "addSubMenu(i)">add submenu</button>
       <ng-container *ngIf = "getSubMenuArray(i).length">
         <!--here we call again to our component-->
          <form-component [form] = "form" 
                          [name] = "name+'.'+i+'.nestedMenu'" 
                          [index] = "index+1" ></form-component>
       </ng-container>
     </div>
  </div>
  </div>`,
})
export class FormMenuComponent  {
  _index:number=0;
  formGroup:FormGroup
  @Input() form: FormGroup;
  @Input() name:string = "nestedMenu";
  @Input('index') set _(value:number){
    this._index=value;
    this.formGroup=(value?this.form.get(this.name).parent:this.form) as FormGroup
  }

  get index()
  {
    return this._index
  }
  get menuArray() {
    return this.form?this.form.get(this.name) as FormArray:null;
  }
  getSubMenuArray(index:number){
    
    return this.form.get(this.name+'.'+index+'.nestedMenu') as FormArray
  }
  
 addMenu()
 {
   this.menuArray.push(setNestedMenu())
 }
 addSubMenu(index:number)
 {
   this.getSubMenuArray(index).push(setNestedMenu())
 }
 removeMenu(index:number)
 {
  this.menuArray.removeAt(index)
 }
}

Посмотрите, как передать имя, форму и индексные переменные

Наш main.component просто

<form-component [form] = "form" [index] = "0"></form-component>

form: FormGroup=new FormGroup({
    nestedMenu:new FormArray([setNestedMenu()])
  })

Смотрите stackblitz

ПРИМЕЧАНИЕ: извините за самоцитирование

Я пробовал модифицировать некоторые настройки. Но у меня возникла проблема. stackblitz.com/edit/angular-pezmpp?file=src/form.component.t‌​s Пожалуйста, помогите мне

Arunkumar 25.04.2023 06:46

я добавил дополнительный массив подменю в этой форме. Но у меня проблема Пожалуйста, помогите мне. Я прикрепил URL-адрес кода. Я не знаю, как исправить эту ошибку. stackblitz.com/edit/angular-pezmpp?file=src/form.component.t‌​s

Arunkumar 26.04.2023 09:34

@Arunkumar, извините за задержку (на прошлой неделе я был очень занят). Я добавил новый ответ, который, надеюсь, поможет

Eliseo 05.05.2023 08:09

Перед ответом передать в форму две переменные: «форма» и «имя» formArray. Это усложняет компонент. Есть еще один лучший подход, который передает "formGroup".

Во-первых, наш компонент имеет ввод «установщика», например

  formGroup:FormGroup
  @Input('form') set __(value:AbstractControl){
    this.formGroup=value as FormGroup
  }

(Необходимо "отлить" управление)

Теперь мы можем использовать что-то вроде

<div *ngIf = "formGroup" [formGroup] = "formgroup">
  ...
  <div formArrayName = "nestedMenu">
     <div *ngFor = "let group of nestedMenuArray?.controls;let i=index"
                [formGroupName] = "i">
        ...
        <ng-container *ngIf = "getNestedMenuArray(i)?.length">
          <!--see we pass as form the "formGroup"-->
          <form-component [form] = "nestedMenuArray.at(i)"  [index] = "index+1" >
          </form-component>
        </ng-container>
     </div>
  </div>

  get nestedMenuArray() {
     return this.formGroup?this.formGroup.get('nestedMenu') as FormArray:null;
  }

  getNestedMenuArray(index:number){
    return  this.nestedMenuArray?this.nestedMenuArray.at(index) as FormArray:null
  }

стекблиц

Другие вопросы по теме