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

问题描述 投票:1回答:2

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(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),
          }));
            });
          });
        });
      });
    }
  }
javascript arrays angular typescript
2个回答
3
投票

开场线[][{}]立即在控制台中绘制。

[]的情况下,数组在记录时没有任何内容,因此浏览器将其绘制为空数组。但是,当您查看并稍后点击小三角形时,数据就会出现。

您可以在控制台中使用此代码重现此行为:

;(function(){ let arr=[]; setTimeout(()=>{ arr[0] = {b:3}; }); return arr;})()

所以你看到的差异与(a)阵列填充的同步性有关。


1
投票

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
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.