如果看图片,这两个数组都由相同类型的对象组成。首先,我使用空数据作为占位符来创建它,但是第二我使用来自服务器的数据来创建它。
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(v的常量值)代码。为什么会这样呢?当我将它们打印出来时,它们似乎是相同的,只是浏览器工具中的[{...}]与[]不同。
如果您想了解我如何创建它们。第一个是路由,第二个是routeslocal。我将它们放在有角度的formcontrol中,这就是如何通过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),
}));
});
});
});
});
}
}
答案 0 :(得分:3)
开始线[]
或[{}]
立即在控制台中绘制。
对于[]
,在记录时数组中没有任何内容,因此浏览器将其绘制为空数组。但是,当您稍后查看并单击小三角形时,数据就存在了。
您可以在控制台中使用以下代码重现此行为:
;(function(){ let arr=[]; setTimeout(()=>{ arr[0] = {b:3}; }); return arr;})()
因此,您看到的差异与数组填充的同步性有关。
答案 1 :(得分:1)
Vato,您的服务中有两个功能:getRequest(requestId)和getAddressPoint(requestVehicles)。想法是返回整个对象。您可以在自己的服务或组件中创建函数。我想在服务中,并返回一个objservable。您必须使用forkJoin和swithMap So。对我来说,检查工作是否可行
**更新,请参见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收到了一个可观察对象数组,在subscription中,它收到了一个数组响应
//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
}
}