可以递归使用组件吗?
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
元素只会添加<app-goal></app-goal>
对象。它不会创建角度组件。它不会绑定您的数据。
此外,如果您使用 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 元素来显示名称)并且它是添加按钮来创建一个较低的目标。以上是关于可以递归使用组件吗?的主要内容,如果未能解决你的问题,请参考以下文章