从Angular 7中的列表中动态添加和删除组件

时间:2019-07-10 13:06:57

标签: angular

在我的一个Angular组件中,我有一个mat-list,我想用它来显示子组件的列表。我想允许用户能够通过单击列表下方的按钮将组件添加到此列表,并通过单击组件本身上的删除按钮从列表中删除组件。< / p>

就上下文而言,正在创建/删除的子组件是与保存有关IP地址范围的信息有关的组件。它包含两个输入,一个用于起始范围,一个用于结束范围。

我可以使用添加功能,但是实现方式似乎并不正确。我目前拥有的方式是持有一个IpRange对象的数组(包含两个字符串的简单对象),然后使用*ngFor每次将一个对象添加到此数组时生成一个新组件。该组件是通过子组件内的@Input ipRange: IpRange生成的。

但是,当我实例化这些新组件时,我是通过将空对象传递给数组来创建它们的,这感觉不对。

ParentTemplate

<div class="row">
            <div class="col-12">
                <mat-list>
                    <app-add-ip-dialog *ngFor="let ipRange of ipRanges" [ipRange]="ipRange"></app-add-ip-dialog>
                </mat-list>
            </div>
        </div>

ParentComponent

export class ParentComponent implements OnInit{

  ipRanges: IpRange[];

  constructor() {}

  ngOnInit() {
    this.ipRanges = [];
  }

  addIpRange(): void {
    this.ipRanges.push({startingRange: '', endingRange: ''});
    console.log(this.ipRanges);
  }
}

ChildComponent

export class AddIpDialogComponent implements OnInit, OnChanges {

  @Input() ipRange: IpRange;

  constructor(){}

  ngOnInit() {
  }

  ngOnChanges(changes: SimpleChanges): void {
    console.log(this.ipRange.startingRange + ' : ' + this.ipRange.endingRange);
  }
}

IpRange界面

export interface IpRange {
    startingRange: string;
    endingRange: string;
}

我想做的是每次用户单击添加按钮时都实例化一个新组件,然后每个组件都可以通过两种方式绑定来跟踪其startingRangeendingRange

然后,当用户想要删除这些组件之一时,他们只需单击组件上的删除按钮,然后将其从列表中删除。

2 个答案:

答案 0 :(得分:0)

这些必须是单独的组件吗?我最近做了一些非常相似的事情,使您能够以表格形式列出要上传的文件,并在其中建立了添加/删除输入功能,该功能将为要上传的每个文件以及何时发布数据创建新的输入。在一个数组中。那条路线可能会更容易。让我知道这是否是您愿意做的更改,我可以向您显示一些代码。我使用_.set

答案 1 :(得分:0)

我建议使用Service作为集中式数据存储,以将ipRanges数据分发到您的组件:

@Injectable({providedIn: 'root'})
export class IpRangesService() {
 ipRanges: ipRange[];
 ngOnInit() {
    this.ipRanges = [];
  }

  addIpRange() {
    this.ipRanges.push({startingRange: '', endingRange: ''});
    console.log(this.ipRanges);
  }
  removeIpRange(index) {
    this.ipRanges.slice(index,1);
  }
  getIpRangeData() {
    return this.ipRanges
  }
}

然后将其分发给您的父组件

在父ts文件中:

export class ParentComponent implements OnInit{

  ipRanges: IpRange[];

  constructor(private ipRangeService : IpRangeService) {}

  ngOnInit() {
    this.ipRanges = this.ipRangeService.getIpRangeData();
  }
}

在您的父HTML模板中,将index属性传递给您的孩子,它充当孩子组件的标识符:

<div class="row">
    <div class="col-12">
        <mat-list>
            <app-add-ip-dialog 
                *ngFor="let ipRange of ipRanges, let i = index" 
                [ipRange]="ipRange"
                [id]="i"> 
            </app-add-ip-dialog>
        </mat-list>
    </div>
</div>

现在您可以从子组件中使用该索引,并使用上述服务提供的方法removeIpRange()删除自身:

export class AddIpDialogComponent implements OnInit, OnChanges {

  @Input() ipRange: IpRange;
  @Input() id: number;
  constructor(private ipRangeService : IpRangeService){}

  ngOnInit() {
  }

  //function that listen to the remove click event
  onRemoveButtonClicked() {
     this.ipRangeService.removeIpRange(id);
  }
}