如果你看图片,两个数组都包含相同类型的对象。首先我用空数据创建它作为占位符,但第二个我用来自服务器的数据创建它。
writeValue(v: any) {
console.log('aaa');
console.log(v);
console.log('aaa');
this.form = new FormArray([]);
for (const value of v) {
console.log('bbb');
console.log(value);
console.log('bbb');
this.form.push(new FormControl(value));
}
this.form.valueChanges.subscribe(res => {
if (this.onChange) {
this.onChange(this.form.value);
}
});
}
对于第一种情况,它遍历所有writeValue代码,对于第二种情况,它不通过for(const值为v)代码。为什么会这样?当我打印出来时,它们似乎与浏览器工具中的一个差异[{...}] vs []不同。
如果你想看看我是如何创建它们的。第一个是路线,第二个是路线本地。我把它们放在有角度的形式控制中,这就是它如何通过controlvalueaccessor获得writeValue。如果你想知道它是如何工作的,你可以查看我之前的问题here。有更多的代码,但它不包括服务。
ngOnInit() {
const routes: any[] = [];
routes.push({ ...dataI });
this.requestForm = this.fb.group({
statusId: null,
requestVehicles: this.fb.array([
this.fb.group({
garageId: 0,
routes: new FormControl(routes),
endDateTime: 0,
})
])
});
if (this.data.isEdit) {
this.Title = 'Edit';
this.data.fService.getRequest(this.data.requestId).subscribe(thisRequest => {
this.requestForm = this.fb.group({
statusId: thisRequest.status,
requestVehicles: this.fb.array([
])
});
thisRequest.requestVehicles.forEach((element, index) => {
const routeslocal: any[] = [];
element.routes.forEach((elementt, indexx) => {
this.data.fService.getAddressPoint(elementt).subscribe(sbed => {
const newRoute = {
addressPointId: sbed.addressPointId,
municipalityId: sbed.municipalityId,
regionId: sbed.regionId,
rvId: element.rvId,
sequenceNumber: indexx,
settlementId: sbed.settlementId,
regionName: sbed.regionName,
municipalityName: sbed.municipalityName,
settlementName: sbed.settlementName,
description: sbed.description,
};
routeslocal.push({...newRoute});
});
});
this.requestVehicles.push(this.fb.group({
endDateTime: new Date(element.endDateTime),
garageId: element.garageId,
routes: new FormControl(routeslocal),
}));
});
});
});
});
}
}
开场线[]
或[{}]
立即在控制台中绘制。
在[]
的情况下,数组在记录时没有任何内容,因此浏览器将其绘制为空数组。但是,当您查看并稍后点击小三角形时,数据就会出现。
您可以在控制台中使用此代码重现此行为:
;(function(){ let arr=[]; setTimeout(()=>{ arr[0] = {b:3}; }); return arr;})()
所以你看到的差异与(a)阵列填充的同步性有关。
Vato,您的服务中有两个函数:getRequest(requestId)和getAddressPoint(requestVehicles)。这个想法是返回一个完整的对象。您可以在自己的服务或组件中创建该功能。我想在服务中,并返回一个obindservable。你必须使用forkJoin和swithMap所以。这对我来说无法检查是否有效
**更新,请参阅stackblitz
getFullRequest(id): Observable<any> {
return this.getRequest(id).pipe(
switchMap((request: any) => {
//here you has the request. We create an array of observables
return forkJoin(
request.requestVehicles.map(
(r: any) => this.getAddressPoint(r))).pipe(map((res: any[]) => {
res.forEach((x: any, index: number) => {
x.sequenceNumber = index
})
return {
statusId: request.statusID,
routes: res
}
})
)
}))
}
然后,在你的组件中
if (this.data.isEdit) {
this.Title = 'Edit';
this.data.fService.getFullRequest(this.data.requestId).subscribe(thisRequest => {
this.requestForm = this.fb.group({
statusId: thisRequest.status,
requestVehicles: thisRequest.routes
});
更新2简要说明了switchMap和forkJoin。
当我们制作this.getRequest(id)
时,我们在请求中收到了一个对象。在这个对象中,我们在requestVehicles中有一个数组(可以是一个对象数组或一个数组数组 - 或字符串 - )。使用此数组的每个元素,我们可以进行调用,但我们不是一对一地进行调用,而是希望将所有这些组合在一起。为此,我们使用forkJoin。 forkJoin收到了一个observable数组,并在subscribe中收到了一个数组中的响应
//if we has an observable like:
getValue(id:number):Observable<any>{
return of({one:id})
}
//and an array like
myArray=[1,2]
//and an array of response whe we can store the responses
response:any[]
//we can do
for (let id of myArray)
{
this.getValue(id).susbcribe(res=>{
this.response.push(res)
})
}
//or
observables:any[]
for (let id of myArray)
{
this.observables.push(this.getValue(id))
}
forkJoin(this.observables).subscribe((res;any[])=>{
//in res[0] we have the result of this.getValue(1)
//in res[1] we have the result of this.getValue(2)
//so, simply
this.response=res
})
//or in a compact way
//with each element of the array
observables=myArray.map(x=>this.getValues(x))
forkJoin(this.observables).subscribe((res;any[])=>{
this.response=res
})
嗯,还有两个问题。我们想为所有响应添加一个新属性“sequenceNumber”。所以我们使用res.forEach(...)
来添加属性。我们希望返回一个具有我们原始请求(statusID)的某些属性的对象,并在带有响应的数组“路由”中。所以我们使用map
来转换响应。在我们上面的简单例子中
//not return simple {one:1}
//return {id:1,one:1}
getResponse(2).pipe.map(res=>{
return {
id:1,
one:res.one
}
}