首页 > 解决方案 > 推入子组件时的数组不更新跟随数据父级传递到角行为中的子级

问题描述

这是我的孩子组件。仍然监听来自父级的更改数据,但在我的代码中,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);
      })
    );
  };


}

我的目的是将来自父级的数据向下发送到另一个数组。

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

也许是因为我使用了错误的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"
        }
    ],

标签: angularrxjsangular9

解决方案


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

<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 属性,而第二个则不会。


推荐阅读