可以递归使用组件吗?

Posted

技术标签:

【中文标题】可以递归使用组件吗?【英文标题】:Kind of recursive usage of an Component possible? 【发布时间】:2019-04-18 23:09:31 【问题描述】:

在搜索了大约两个小时的解决方案后,我决定询问一些专业人士,他们怀疑解决方案可能非常简单。

这是一个 Angular7 项目。 我想在我的目标组件中有一个带有“+”按钮的“目标”。当您单击该按钮时,我希望将另一个目标添加到页面中。所以我想点击目标组件的一个按钮来创建一个新目标,这对我来说有点像递归。

goals.component.html

<input type="text" value="Ich brauche einen Laptop für maximal 1000 Euro.">
<br/>
<br/>
<app-goal id="lastGivenId+1"></app-goal>

goals.component.ts:

import  Component, OnInit  from '@angular/core';

@Component(
  selector: 'app-goals',
  templateUrl: './goals.component.html',
  styleUrls: ['./goals.component.scss']
)
export class GoalsComponent implements OnInit 
  lastGivenId: number = 0;
  constructor()  

  ngOnInit() 
  


goal.component.ts 和goal.component.html:

//Typescript code
import  Component, OnInit, Input  from '@angular/core';

@Component(
  selector: 'app-goal',
  templateUrl: './goal.component.html',
  styleUrls: ['./goal.component.scss']
)
export class GoalComponent implements OnInit 
  @Input() id : number;

  constructor()  

  ngOnInit() 
  
  onAddLowerGoal(currentGoalID:number)
    // var goalElement = document.registerElement('app-goal');
    // document.body.appendChild(new goalElement());
    let newGoal = document.createElement("app-goal");
    newGoal.setAttribute("id", "999");
    let currentGoal = document.getElementById(currentGoalID.toString());
    document.body.insertBefore(newGoal, currentGoal);
  
<html>
<div id="id" class="goal">goalid</div>
<button id="AddLowerGoal1" (click)="onAddLowerGoal(999)">+</button>
</html>

这样,它创建了一个 app-goal 元素,但是 app-goal 元素中的 div 和 button 元素丢失了。 如何解决这个问题?欢迎任何帮助。提前致谢。

【问题讨论】:

【参考方案1】:

第一眼:从goal.component.html 文件中删除html 标签。

下一步:您可以使用 Angular 递归添加 app-goal。以javascript方式插入app-goal元素只会添加&lt;app-goal&gt;&lt;/app-goal&gt;对象。它不会创建角度组件。它不会绑定您的数据。

此外,如果您使用 Angular 的 @Input,您需要使用方括号分配组件输入。不要使用标签。

goals.component.html:

<input type="text" value="Ich brauche einen Laptop für maximal 1000 Euro.">
<br/>
<br/>
<app-goal [id]="lastGivenId+1"></app-goal>

goal.component.html:

<div id="id" class="goal">goalid</div>
<button id="AddLowerGoal1" (click)="onAddLowerGoal(999)">+</button>
<div *ngFor="let subGoal of subGoals">
  <app-goal [id]="subGoal.id"></app-goal>
</div>

目标.component.ts:

import  Component, OnInit, Input  from '@angular/core';

@Component(
  selector: 'app-goal',
  templateUrl: './goal.component.html',
  styleUrls: ['./goal.component.scss']
)
export class GoalComponent implements OnInit 
  @Input() id : number;
  subGoals: Array<any> = [];

  constructor()  

  ngOnInit()  

  onAddLowerGoal(currentGoalID: number)
    this.subGoals.push(id: currentGoalID);
  

您还可以使用服务来存储您的目标和子目标,以便以后访问它们。

【讨论】:

【参考方案2】:

我认为您正在寻找的是带有FormArray 的响应式表单,并带有动态添加的表单控件。

看看这个例如:

import  Component  from '@angular/core';
import  FormControl, FormGroup, FormArray, FormBuilder  from '@angular/forms';

@Component(...)
export class GoalsComponent  

  goalsForm: FormGroup;

  constructor(private fb: FormBuilder) 

  ngOnInit() 
    this.goalsForm = this.fb.group(
      goals: this.fb.array([])
    );
  

  onFormSubmit() 
    console.log('Form Value: ', this.goalsForm.value);
  

  get goals() 
    return (<FormArray>this.goalsForm.get('goals')).controls;
  

  addGoal() 
    (<FormArray>this.goalsForm.get('goals')).push(this.fb.control(null));
  


下面是这个模板:

<h2>Goals:</h2>
<form [formGroup]="goalsForm" (submit)="onFormSubmit()">
  <button type="button" (click)="addGoal()">Add Goal</button>
  <hr>
  <div *ngFor="let goal of goals; let i = index;" formArrayName="goals">
    <div>
      <label for="goal">Goal  i + 1 : </label>
      <input type="text" id="goal" [formControlName]="i">
    </div>
    <br>
  </div>
  <hr>
  <button>Submit Form</button>
</form>

这里有一个Sample StackBlitz 供您参考。

【讨论】:

非常感谢您的回答。但是我希望在您的 Sample StackBlitz 中发生的是,当单击“添加”按钮时,会出现另一个“添加”按钮。问题是我想要有一个更高的目标,并且能够为那个更高的目标创建一个更低的目标。 那么每个较低的目标会有自己的较低的目标吗? 没错。每个目标(上限或下限)都可以有它自己的下限目标,但不是必须的。 一个上层目标也可以有多个下层目标。每个目标都应该有一个名称(我使用了一个 div 元素来显示名称)并且它是添加按钮来创建一个较低的目标。

以上是关于可以递归使用组件吗?的主要内容,如果未能解决你的问题,请参考以下文章

vuejs 递归单文件组件

Vuejs:动态递归组件(树状结构)

Vue3_15(全局组件,局部组件,递归组件)

vuejs递归组件

vue递归组件的一些理解

vue递归组件 (树形控件 )