【问题标题】:[] vs [{...}] in browser tools, while both having same objects浏览器工具中的 [] 与 [{...}],同时具有相同的对象
【发布时间】:2019-09-07 10:01:29
【问题描述】:

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

  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 values of v) 代码。为什么会这样?当我将它们打印出来时,它们似乎是相同的,除了浏览器工具中的 [{...}] 与 [] 的一个区别。

如果你想看看我是如何创建它们的。第一个是路由,第二个是本地路由。我把它们放在有角度的表单控件中,这就是它如何通过 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


    【解决方案1】:

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

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

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

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

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

    【讨论】:

      【解决方案2】:

      Vato,您的服务中有两个函数:getRequest(requestId) 和 getAddressPoint(requestVehicles)。这个想法是返回一个完整的对象。您可以在自己的服务或组件中创建功能。我想在服务中,并返回一个 objservable。您必须使用 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
              });
      

      Update 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
          }
      }
      

      【讨论】:

      • getAddressPoint() 请求接受一个路由。所以我需要多次调用它 request -> foreach requestVehicle -> foreach route -> call getAddressPoint(route).
      • getAddressPoint 返回每个地址,但现在填充了名称,而不仅仅是 id。我不擅长 rxjs,但据我了解,您希望 getAddressPoint 返回数组。它实际上返回一个路由对象,但现在已填充。
      • 我更新了我的答案,以解释如何发出一个返回具有数组属性的对象的请求
      • 我想说的是我的请求返回更像这样 ({ statusID: 1, requestVehicles: [{routes: [1, 2]}, {routes: [2]}] } )。它有多个请求车辆,每个请求车辆都有多条路线。
      • stackblitz.com/edit/angular-nvw54p 我分叉并编辑了 getRequest 行。我需要使用另一张地图吗?在这种情况下?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-04
      • 2012-09-07
      • 1970-01-01
      • 1970-01-01
      • 2012-09-27
      • 2017-10-07
      • 1970-01-01
      相关资源
      最近更新 更多