如何在 Angular 中推送 Children
How to push Children in Angular
我正在编写一个接受输入的简单节点树应用程序,但我无法显示通过输入创建的 children。整体 objective 是打印输入的 children 的数量,并且所有 children 也都在输入的范围内。我显然可以打印一个新节点,但我的逻辑不起作用,因为 child of "root" 并且 children 的数量也没有打印。请帮忙。任何指导都会真正有帮助和赞赏。我是 Angular 的新手。我错过了什么?
这是我的:
nodetree.component.html
<div class="container">
<div class= "input-div">
<input type="text" class= "node-input" placeholder ="Enter a Name" [(ngModel)]="nodeName"
(keyup.enter)="addNode()">
<input type="text" class= "node-input" placeholder ="Number of Children" [(ngModel)]="nodeChildren"
(keyup.enter)="addNode()">
<input type="text" class= "node-input" placeholder ="Range Minimum" [(ngModel)]="nodeRangeMin"
(keyup.enter)="addNode()">
<input type="text" class= "node-input" placeholder ="Range Maximum" [(ngModel)]="nodeRangeMax"
(keyup.enter)="addNode()">
</div>
<div class="col-9 text-center">
<ul *ngIf="nodes">
<li class="row node" *ngFor="let node of nodes">
<span *ngIf="!node.editing; else editingNode" class="node-name" (dblclick)="editNode(node)">
> {{ node.name }}
</span>
<ng-template #editingNode>
<input type="text" class= "node-edit" [(ngModel)]="node.name" (blur)="editDone(node)" (keyup.enter)="editDone(node)" autofocus>
</ng-template>
<span class="node-range">
{{ node.rangeMin }}-{{ node.rangeMax }}
</span>
<div class="remove-node" (click)="deleteNode(node.name)">
×
</div>
</li>
</ul>
</div>
</div>
和 nodetree.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'nodetree',
templateUrl: './nodetree.component.html',
styleUrls: ['./nodetree.component.scss']
})
export class NodetreeComponent implements OnInit {
nodes: Node[];
nodeName: string;
nodeChildren: Node[];
nodeRangeMin: number;
nodeRangeMax: number;
nodeChildNumber: number;
constructor() { }
ngOnInit() {
this.nodeName = '';
this.nodeRangeMin = undefined;
this.nodeRangeMax = undefined;
this.nodeChildren = [];
this.nodeChildNumber = undefined;
this.nodes = [
{
name: 'Root',
rangeMin: 12,
rangeMax: 20,
childNumber: undefined,
editing: false,
hasChildren: true,
showChildren: true,
children:[
{
name: 'Bob',
rangeMin: 17,
rangeMax: 30,
childNumber: undefined,
editing: false,
hasChildren: true,
showChildren: true,
children:[]
},
{
name: '',
rangeMin: undefined,
rangeMax: undefined,
childNumber: undefined,
editing: false,
hasChildren: false,
showChildren: true,
children:[]
},
]
}
]
}
addNode(): void {
// if(this.nodeName.trim().length === 0) {
// return;
// }
var nodeRangeMin = undefined,
nodeRangeMax = undefined,
nodeChildNumber= undefined,
nodeName = [];
var nodeName = [];
while(nodeName.length < nodeChildNumber){
var r = Math.floor(Math.random()*(nodeRangeMax - nodeRangeMin) + nodeRangeMin);
if(nodeName.indexOf(r) === -1) nodeName.push(r);
return;
}
this.nodes.push({
name: this.nodeName,
rangeMin: this.nodeRangeMin,
rangeMax: this.nodeRangeMax,
childNumber: this.nodeChildNumber,
editing: false,
hasChildren: false,
showChildren: false,
children:[]
})
this.nodeName = '';
this.nodeRangeMin = undefined;
this.nodeRangeMax = undefined;
this.nodeChildNumber = undefined;
}
deleteNode(name: string): void {
this.nodes = this.nodes.filter(node => node.name !== name);
}
editNode(node: Node): void {
node.editing = true;
}
editDone(node: Node): void {
node.editing = false;
}
toggleChild(node: Node) {
node.showChildren = !node.showChildren;
}
}
interface Node {
name: string;
rangeMin: number,
rangeMax: number,
childNumber: number,
editing: boolean;
hasChildren: boolean;
showChildren: boolean;
children: Node[];
}
根据我们的谈话,您需要以下解决方案。
这是一个有效的 blitz
让我们总结一下您要尝试做的事情。
您将拥有一个 root
并使用给定的 name
numberOfChildren
rangeMin
和 rangeMax
创建 children
。这个child会有和numberOfChildren
一样多的children,名字会在rangeMin
和rangeMax
之间随机决定。
让我们创建一个ChildComponent
child.component.ts
export type ChildModel = {
name: string;
rangeMin: number;
rangeMax: number;
children: number[];
};
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
@Input() model: ChildModel;
constructor() { }
ngOnInit() {
}
}
child.component.html
<ng-container *ngIf="model">
<span>
> {{ model.name }}
</span>
<span class="node-range">
{{ model.rangeMin }}-{{ model.rangeMax }}
</span>
<ul>
<li *ngFor="let child of model.children">
{{child}}
</li>
</ul>
</ng-container>
这是
parent.component
@Component({
selector: 'app-parent',
template: `
<div class= "input-div">
<input type="text" class= "node-input" placeholder ="Enter a Name" [(ngModel)]="nodeName"
(keyup.enter)="addNode()">
<input type="number" class= "node-input" placeholder ="Number of Children" [(ngModel)]="nodeChildren"
(keyup.enter)="addNode()">
<input type="number" class= "node-input" placeholder ="Range Minimum" [(ngModel)]="nodeRangeMin"
(keyup.enter)="addNode()">
<input type="number" class= "node-input" placeholder ="Range Maximum" [(ngModel)]="nodeRangeMax"
(keyup.enter)="addNode()">
</div>
<app-child *ngFor="let child of children" [model]="child"></app-child>
`
})
export class ParentComponent implements OnInit {
children: ChildModel[] = [];
nodeName = '';
nodeChildren = 0;
nodeRangeMin = 0;
nodeRangeMax = 0;
constructor() { }
ngOnInit() {
}
addNode() {
this.children.push({
name: this.nodeName,
rangeMin: this.nodeRangeMin,
rangeMax: this.nodeRangeMax,
children: this.generateChildren()
});
this.clearInputs();
}
private generateChildren() {
return [...new Array(this.nodeChildren).fill(0)].map(_ => this.getRandom());
}
getRandom() {
return Math.floor(Math.random()*(this.nodeRangeMax - this.nodeRangeMin) + this.nodeRangeMin);
}
clearInputs() {
this.nodeName = '';
this.nodeChildren = 0;
this.nodeRangeMin = 0;
this.nodeRangeMax = 0;
}
}
我正在编写一个接受输入的简单节点树应用程序,但我无法显示通过输入创建的 children。整体 objective 是打印输入的 children 的数量,并且所有 children 也都在输入的范围内。我显然可以打印一个新节点,但我的逻辑不起作用,因为 child of "root" 并且 children 的数量也没有打印。请帮忙。任何指导都会真正有帮助和赞赏。我是 Angular 的新手。我错过了什么?
这是我的:
nodetree.component.html
<div class="container">
<div class= "input-div">
<input type="text" class= "node-input" placeholder ="Enter a Name" [(ngModel)]="nodeName"
(keyup.enter)="addNode()">
<input type="text" class= "node-input" placeholder ="Number of Children" [(ngModel)]="nodeChildren"
(keyup.enter)="addNode()">
<input type="text" class= "node-input" placeholder ="Range Minimum" [(ngModel)]="nodeRangeMin"
(keyup.enter)="addNode()">
<input type="text" class= "node-input" placeholder ="Range Maximum" [(ngModel)]="nodeRangeMax"
(keyup.enter)="addNode()">
</div>
<div class="col-9 text-center">
<ul *ngIf="nodes">
<li class="row node" *ngFor="let node of nodes">
<span *ngIf="!node.editing; else editingNode" class="node-name" (dblclick)="editNode(node)">
> {{ node.name }}
</span>
<ng-template #editingNode>
<input type="text" class= "node-edit" [(ngModel)]="node.name" (blur)="editDone(node)" (keyup.enter)="editDone(node)" autofocus>
</ng-template>
<span class="node-range">
{{ node.rangeMin }}-{{ node.rangeMax }}
</span>
<div class="remove-node" (click)="deleteNode(node.name)">
×
</div>
</li>
</ul>
</div>
</div>
和 nodetree.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'nodetree',
templateUrl: './nodetree.component.html',
styleUrls: ['./nodetree.component.scss']
})
export class NodetreeComponent implements OnInit {
nodes: Node[];
nodeName: string;
nodeChildren: Node[];
nodeRangeMin: number;
nodeRangeMax: number;
nodeChildNumber: number;
constructor() { }
ngOnInit() {
this.nodeName = '';
this.nodeRangeMin = undefined;
this.nodeRangeMax = undefined;
this.nodeChildren = [];
this.nodeChildNumber = undefined;
this.nodes = [
{
name: 'Root',
rangeMin: 12,
rangeMax: 20,
childNumber: undefined,
editing: false,
hasChildren: true,
showChildren: true,
children:[
{
name: 'Bob',
rangeMin: 17,
rangeMax: 30,
childNumber: undefined,
editing: false,
hasChildren: true,
showChildren: true,
children:[]
},
{
name: '',
rangeMin: undefined,
rangeMax: undefined,
childNumber: undefined,
editing: false,
hasChildren: false,
showChildren: true,
children:[]
},
]
}
]
}
addNode(): void {
// if(this.nodeName.trim().length === 0) {
// return;
// }
var nodeRangeMin = undefined,
nodeRangeMax = undefined,
nodeChildNumber= undefined,
nodeName = [];
var nodeName = [];
while(nodeName.length < nodeChildNumber){
var r = Math.floor(Math.random()*(nodeRangeMax - nodeRangeMin) + nodeRangeMin);
if(nodeName.indexOf(r) === -1) nodeName.push(r);
return;
}
this.nodes.push({
name: this.nodeName,
rangeMin: this.nodeRangeMin,
rangeMax: this.nodeRangeMax,
childNumber: this.nodeChildNumber,
editing: false,
hasChildren: false,
showChildren: false,
children:[]
})
this.nodeName = '';
this.nodeRangeMin = undefined;
this.nodeRangeMax = undefined;
this.nodeChildNumber = undefined;
}
deleteNode(name: string): void {
this.nodes = this.nodes.filter(node => node.name !== name);
}
editNode(node: Node): void {
node.editing = true;
}
editDone(node: Node): void {
node.editing = false;
}
toggleChild(node: Node) {
node.showChildren = !node.showChildren;
}
}
interface Node {
name: string;
rangeMin: number,
rangeMax: number,
childNumber: number,
editing: boolean;
hasChildren: boolean;
showChildren: boolean;
children: Node[];
}
根据我们的谈话,您需要以下解决方案。
这是一个有效的 blitz
让我们总结一下您要尝试做的事情。
您将拥有一个 root
并使用给定的 name
numberOfChildren
rangeMin
和 rangeMax
创建 children
。这个child会有和numberOfChildren
一样多的children,名字会在rangeMin
和rangeMax
之间随机决定。
让我们创建一个ChildComponent
child.component.ts
export type ChildModel = {
name: string;
rangeMin: number;
rangeMax: number;
children: number[];
};
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
@Input() model: ChildModel;
constructor() { }
ngOnInit() {
}
}
child.component.html
<ng-container *ngIf="model">
<span>
> {{ model.name }}
</span>
<span class="node-range">
{{ model.rangeMin }}-{{ model.rangeMax }}
</span>
<ul>
<li *ngFor="let child of model.children">
{{child}}
</li>
</ul>
</ng-container>
这是
parent.component
@Component({
selector: 'app-parent',
template: `
<div class= "input-div">
<input type="text" class= "node-input" placeholder ="Enter a Name" [(ngModel)]="nodeName"
(keyup.enter)="addNode()">
<input type="number" class= "node-input" placeholder ="Number of Children" [(ngModel)]="nodeChildren"
(keyup.enter)="addNode()">
<input type="number" class= "node-input" placeholder ="Range Minimum" [(ngModel)]="nodeRangeMin"
(keyup.enter)="addNode()">
<input type="number" class= "node-input" placeholder ="Range Maximum" [(ngModel)]="nodeRangeMax"
(keyup.enter)="addNode()">
</div>
<app-child *ngFor="let child of children" [model]="child"></app-child>
`
})
export class ParentComponent implements OnInit {
children: ChildModel[] = [];
nodeName = '';
nodeChildren = 0;
nodeRangeMin = 0;
nodeRangeMax = 0;
constructor() { }
ngOnInit() {
}
addNode() {
this.children.push({
name: this.nodeName,
rangeMin: this.nodeRangeMin,
rangeMax: this.nodeRangeMax,
children: this.generateChildren()
});
this.clearInputs();
}
private generateChildren() {
return [...new Array(this.nodeChildren).fill(0)].map(_ => this.getRandom());
}
getRandom() {
return Math.floor(Math.random()*(this.nodeRangeMax - this.nodeRangeMin) + this.nodeRangeMin);
}
clearInputs() {
this.nodeName = '';
this.nodeChildren = 0;
this.nodeRangeMin = 0;
this.nodeRangeMax = 0;
}
}