Angular2 ngOnChanges 克隆@Input 数组

Angular2 ngOnChanges clone @Input array

我正在使用 DashboardComponent 从我的 DashboardService 获取数据。该组件然后将我的对象数组传递到我的表单组件。

(post 底部的 Plunkr link)

DashboardComponent.ts

 private bottleArray: Bottle[] = [];

  ngOnInit() {
    // Get bottle types from service to the form needing them
    this.dashboardService.getBottleTypesAndNames()
      .subscribe(bottlesData => {
        bottlesData.forEach(bottle => {
          // Convert to Bottle type
          let bottleObject: Bottle = new Bottle(bottle.bottleTypeId, bottle.bottleName);
          this.bottleArray.push(bottleObject);
        });
      });
  }

DashboardComponent.html

<ct-create-order-form [bottleArray]="bottleArray"> </ct-create-order-form>

我这样做是为了让我的 link 到我的 Dashboard 的表单组件不会调用我的服务。

我正在尝试 clone 我的 @Input 以便我从表单更新的数据不会 link 编辑到我的父组件(仪表板),但我似乎做不到它......见下面的代码:

CreateOrderFormComponent.ts

export class CreateOrderFormComponent implements OnChanges {
  @Input() private bottleArray: Bottle[];

  constructor() { }

  private clonedBottleArray: BottleCommand[];

  ngOnChanges(changes) {

    if (changes.bottleArray) {
      let test: BottleCommand[] = changes.bottleArray.currentValue;

      // Cloning
      console.log(test);  // Array of 6 Bottles

      this.clonedBottleArray = [...test];       
      console.log(this.clonedBottleArray);         // Empty Array
      this.clonedBottleArray = Array.from(test);
      console.log(this.clonedBottleArray);         // Empty Array
      this.clonedBottleArray = test.slice();
      console.log(this.clonedBottleArray);         // Empty Array

      this.clonedBottleArray = test;
      console.log(this.clonedBottleArray);         // Array of 6 bottles
   }
}

有什么方法可以实现我正在做的事情吗?我不明白为什么我在获取数据时无法克隆输入?

从这个由 AngularConnect 制作的 Youtube 视频中,他正在做完全相同的事情,除了他正在操纵一个对象,而我正在操纵一个对象数组。

https://youtu.be/-nsedZwvl9U?t=12m22s


EDIT :创建 Plunkr 后,它似乎在那里正常工作。

https://plnkr.co/edit/js1vl0fcgOKtQNqXsWTL?p=preview


编辑 2:在我的 DashboardComponentngOnInit(),如果我模拟数据,它会在我的子组件中正确克隆。

看起来 angular OnChange 由于其特定的检查方式而没有触发,这里是来自 的简短解释:

During change detection, when Angular checks components' input properties for change, it uses (essentially) === for dirty checking. For arrays, this means the array references (only) are dirty checked. Since the rawLapsData array reference isn't changing, ngOnChanges() will not be called.

在您的示例中,您在 bottleArray.pushing 瓶子,因此 OnChange 不会在同一数组引用上触发。

要获得更改,您可以使用 DoCheck:

ngDoCheck() {
  console.log(this.bottleArray);
  this.clonedBottleArray = [...this.bottleArray].slice(0, 4);
  console.log(this.clonedBottleArray);
}

它会在您将新值推送到 bottleArray 时触发。工作 plunker here.