Array when push in child components not update follow data parent pass into child in Angular Behavior

Array when push in child components not update follow data parent pass into child in Angular Behavior

这是我的 child 组件。仍然监听来自 parent 的变化数据,但在我的代码中,ArrayObjectParser 不监听跟随它的变化。那么这里有什么想法吗?请帮助我。

import { Component, OnInit, Inject, ViewChild, Input } from '@angular/core';
import { FormTemplateModel, PageBuilderModel, SectionLayoutModel, EntityMappings } from '../../models/dynamic-form.model'
import { BehaviorSubject } from 'rxjs';
import { skipWhile, take } from 'rxjs/operators';
@Component({
  selector: 'm-entity-mappping',
  templateUrl: './entity-mappping.component.html',
  styleUrls: ['./entity-mappping.component.scss']
})
export class EntityMapppingComponent implements OnInit {

  private _obsers: any[] = [];

  @ViewChild('inputControl') nameInput: any;

  @Input()
  set data(value) {
    this.viewData.TemplateData$.next(value);
  };

  get data() {
    return this.viewData.TemplateData$.getValue();
  }

  constructor() { }

  viewModel: any = {
    DynamicPreview: new FormTemplateModel()
  }

  viewData: any = {
    TemplateData$: new BehaviorSubject<FormTemplateModel>(null),
    FormEntityData: new Array<EntityMappings>()
  };

  ngOnInit(): void {
    this.bindSubscribes();
  }

  ngOnDestroy() {
    for (let obs of this._obsers) {
      obs.unsubscribe();
    }
  }
  
  parserDataToObjectEntity(data: FormTemplateModel) {
    const ArrayObjectParser = [];
    data.LayoutBuilder.forEach((element: PageBuilderModel) => { //Still working right here
      element.SectionLayouts.forEach((section:SectionLayoutModel) => {
        if (section.Type == "Container") {
          section.FieldLayouts.forEach((field:SectionLayoutModel) => { //Breaking right here

            let object : EntityMappings  = {
              Id: field.Id,
              Title: field.Title,
              EntityProperty: ""
            }            
            ArrayObjectParser.push({ ...object });
          })
        }
        else {
          let object = {
            Id: section.Id,
            Title: section.Title,
            EntityProperty: ""
          }
          ArrayObjectParser.push({ ...object });
        }
      })
    }); 
    console.log(ArrayObjectParser);
    return ArrayObjectParser;
  }


  private bindSubscribes() {

    this._obsers.push(
      this.viewData.TemplateData$.subscribe((value: FormTemplateModel) => {
        this.parserDataToObjectEntity(value);
      })
    );
  };


}

我的目的是将数据从 parent 发送到另一个数组。

我希望每次 parent 更改数据时,我的数据都会更改,但我的代码在使用时无效。

可能是我用错了foreach?

示例数据我来了

{
  "Id": "",
  "Name": {
    "vi": "Name"
  },
  "LayoutBuilder": [
    {
      "Id": "Page1",
      "Title": {
        "vi": "ten page",
        "en": "page name"
      },
      "Order": 1,
      "SectionLayouts": [
        {
          "Id": "Page1_Section1",
          "Order": 1,
          "Title": {
            "vi": "Phan"
          },
          "Type": "Container",
          "FieldLayouts": [
            {
              "Id": "Page1_Section1_Field1",
              "Order": 1,
              "Title": {
                "vi": "Cau hoi"
              },
              "Type": "Input",
              "Required": false,
              "SubType": "Text"
            }
          ]
        }
      ]
    }
  ]
}

然后 FormEntityData 像这里一样变成 ArrayObjectParser

    "EntityMappings":[
        {
            "Id":"Page1_Section1_Control1",
            "Title":{"vi":"Ten field", "en":"Field Name"},
            "EntityProperty":"Hovaten"
        },
        {
            "Id":"Page1_Section1_Control2",
            "Title":{"vi":"Ten field", "en":"Field Name"},
            "EntityProperty":"Email"
        }
    ],

输入属性只监听对象引用的变化,而不是数据本身。如果你希望每次都将数据下推到子组件,你将需要创建一个新数组。

<child [data]="data"></child>

如果你这样做 this.data.push(val) 这将不会触发输入 属性 来识别新数组,因为它仍然是对数组的相同引用。对于要触发的输入属性,您需要将数据更改为对具有 this.data = [...this.data, val] 的新数组的引用,因为数据现在是一个新对象,输入 属性 将触发。

这是创建新数组的 StackBlitz https://stackblitz.com/edit/angular-ivy-mqvdf6?file=src%2Fapp%2Fapp.component.ts

这是将数据推送到数组的一个 https://stackblitz.com/edit/angular-ivy-pfcms1?file=src%2Fapp%2Fapp.component.ts

注意第一个如何在每次点击时触发 setter 属性 但第二个不会。