[] vs [{...}]在浏览器工具中,而两者都有相同的对象

时间:2019-04-17 08:05:10

标签: javascript arrays angular typescript

enter image description here

如果看图片,这两个数组都由相同类型的对象组成。首先,我使用空数据作为占位符来创建它,但是第二我使用来自服务器的数据来创建它。

  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),
          }));
            });
          });
        });
      });
    }
  }

2 个答案:

答案 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
    }
}