angular - 推入子组件时的数组不更新跟随数据父级传递到角行为中的子级
问题描述
这是我的孩子组件。仍然监听来自父级的更改数据,但在我的代码中,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"
}
],
解决方案
输入属性只监听对象变化的引用,而不是数据本身。如果您希望每次将数据下推到子组件,则需要创建一个新数组。
<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 属性,而第二个则不会。
推荐阅读
- recursion - Jackson:如何通过仅在子集合中添加 ID 字段来防止递归调用
- ios - iOS13启动画面主题
- python-3.x - 如何将微控制器连接到 GPS 模块并接收位置
- wso2 - 有没有办法为 JMS (ActiveMQ) 代理连接使用基于事件的入站端点
- azure-devops - 获取“请求取消任务。System.Threading.Tasks.TaskCanceledException:任务已取消。” 下载工件时
- c# - 文本框下的 C# 下拉菜单,如组合框
- mysql - 从连接的 sql 表中获取结果
- excel - Excel VBA - 在 SharePoint 上查找文件的本地文件位置
- logging - Yii2:如何在 Codeception 中写日志?
- sql - SQL Server:在一个 sql 查询中添加多行