嗨,我使用了反应性表单将对象数组绑定到formArray,但是在这里,如果我选择一个节中的任何一个项,然后单击“向右移动/向左移动”,那么整个对象已经从一个部分移动到另一个部分。但是该功能运行良好,但我无法检测form.valuechanges()中从一个部分到另一个部分生成的chnage。有人能帮我检测一下变化吗?因为已从一个部分移到另一个部分,这里我想要更改检测,但功能必须正常工作,我指的是要从一个部分移动到另一个部分的整个对象。
提前谢谢。
我已经在这里使用demo2了,我希望我以前发布的demo1能够像这样使用work数组工作。演示2
演示:演示1
TS:
private settingsGroupInfoForm() {
if (!this.agentDetailsList) {
// Add
this.agentGroupViewInfoForm = this.FB.group({
agentGroupView: this.FB.array(
this.agentInView.map(x=>(x))
),
})
} else {
// Edit
if (this.agentDetailsList) {
this.agentGroupViewInfoForm = this.FB.group({
agentGroupView: this.FB.array(this.agentInView.map(x=>(x))),
})
}
this.agentGroupViewInfoForm.valueChanges.subscribe(data => {
this.formEdit = true;
console.log('agentGroupViewInfoForm', this.formEdit)
})
}
}HTML:
<div class="card-body overflow-auto py-0" *ngIf="agentGroupViewInfoForm"
[formGroup]="agentGroupViewInfoForm">
<ul class="list-group list-group-flush" *ngFor="let child of agentInView" name="agentInGroup" formArrayName="agentGroupView">
<li class="list-group-item {{isInActiveItems(child) ? 'active' : ''}}" (click)="toggleActiveItem(child)">
{{child.value}}
</li>
</ul>
</div>发布于 2020-02-27 08:15:45
你的问题
设计
对于角度上几乎所有基于组件的问题,您应该首先考虑模型。你的模型是国王,其他一切都是围绕着它建立的。
在演示中,您要在列表之间移动项目。您正在更新模型并将HTML绑定到该模型。没有什么不对的-这是正确的方法和工作。
这里的另一个挑战是,您也希望移动表单组。我们仍然需要考虑模型--首先,同时考虑移动相关状态,同时在列表之间移动项目。
抽象地说,您目前
list1: [];
selected1: [];
list2: [];
selected2: [];如果要将项目从1 -> 2中移除,则移动方法将将所选项从items1移到items2。很简单。
一旦添加了表单,就会有如下结构:
list1: [];
selected1: [];
form1: FormGroup;
formArray1: FormArray;
list2: [];
selected2: [];
form2: FormGroup;
formArray2: FormArray;当您将项目从1 -> 2中移动时,您将继续将项目从list1移动到list2,但现在还需要从formArray1中删除相关项并将其添加到formArray2。
我正在存储对表单数组的引用,以便以后更容易地使用它们。
构建表单
使用表单数组可以说是这个答案中最复杂的部分。表单数组的关键是HTML结构模仿您构建的FormGroup对象的结构。
我们可以使用FormBuilder从数组构建表单,并按如下方式绑定到它:
component.ts
buildForm() {
this.model = [
{ value: 'a' }, { value: 'b' }, { value: 'c' }
];
// create a form group for each item in the model
const formGroups = this.model.map(x => this.formBuilder.group({
value: this.formBuilder.control(x.value)
}));
// create a form array for the groups
const formArray = this.formBuilder.array(formGroups);
// create the top-level form
this.form = this.formBuilder.group({
array: formArray
});
}并绑定到HTML中,如下所示:
<form [formGroup]="form1" (submit)="onSubmit()">
<div formArrayName="array">
<div *ngFor="let item of list1; let i = index" [formGroupName]="i">
<input formControlName="value" />
</div>
</div>
<button>Submit</button>
</form>这将为数组中的每个项生成一个输入,分别包含值"a“、"b”和"c“。
移动物品
在数组之间移动项是一个简单的javascript问题。我们需要splice源数组和push到目标数组。
若要将项目从列表1移动到列表2:
// move selected items from model 1
this.selected1.forEach(item => {
const index = this.list1.indexOf(item);
this.list1.splice(index, 1);
this.list2.push(item);
});
this.selected1.length = 0;这将循环遍历列表1中的每个选定项目,将其从列表中剪接,然后将其推入列表2,然后清除所选的项目;
移动形群
您将在移动项目的同时移动表单组。它在概念上是相似的-你从一个移除,然后添加到另一个。您从您的模型构建了表单数组,因此您知道您的索引匹配。
// move selected items from model 1
this.selected1.forEach(item => {
const index = this.list1.indexOf(item);
const formGroup: FormGroup = this.formArray1.controls[index] as FormGroup;
this.list1.splice(index, 1);
// move between form arrays
this.formArray1.removeAt(index);
this.formArray2.push(formGroup);
this.list2.push(item);
});请注意,在表单数组之间有2行可以移动,它们看起来类似于用于在常规数组之间移动的2行。
formArray.removeAt(index)和formArray.push(formGroup)正在搬家。表单数组的不同之处在于,我们需要首先使用this.formArray1.controls[index] as FormGroup;获得对它的引用。
演示:https://stackblitz.com/edit/angular-3cwnsv
警诫
在此设计中,从数组和窗体中移除和添加的顺序非常重要。您正在将HTML绑定到数组和表单。您正在创建输入数组,方法是遍历数组,并将每个项绑定到表单数组中的ith组。如果首先从表单中删除,则现在在数组中有n项,在窗体数组中有n - 1项。当试图绑定到未定义的nth form组时,将出现错误。
您现在正在使用多个操作执行事务。
除了确保删除并按正确的顺序添加之外,还有一种方法是使用OnPush更改检测。阅读这一点,因为这是一个很好的策略,除了最简单的应用程序。
下一步
为了回答的目的,我保持了我的演示的简单性。就目前情况而言,它并不是特别可伸缩或可重用的。有很多重复的代码和错误的命名,试图避免被与应用程序相关的嵌套组件和属性名称分散注意力。
实际上,您可能希望创建一个子组件,负责我复制的大量代码。这个设计绝对超出了这个问题的范围。
https://stackoverflow.com/questions/60360555
复制相似问题