[] против [{...}] в инструментах браузера, в то время как оба имеют одинаковые объекты - PullRequest
1 голос
/ 17 апреля 2019

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 values ​​of v). почему это происходит? когда я их распечатываю, они кажутся одинаковыми, за исключением одного отличия [{...}] от [] в инструментах браузера.

Если вы хотите посмотреть, как я их создаю. Первый - маршруты, а второй - маршруты. Я поместил их в угловую форму управления, и вот как это получается записать значение через controlvalue accessor. Если вы хотите узнать, как это работает, вы можете проверить мой предыдущий вопрос здесь . есть еще код, но он не включает службу.

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 ]

3 голосов
/ 17 апреля 2019

Открывающая линия, [] или [{}], сразу отображается в консоли.

В случае [] во время регистрации в массиве ничего не было, поэтому браузер отображает его как пустой массив. Но данные присутствовали, когда вы смотрели на них и нажимали на маленький треугольник, позже.

Вы можете воспроизвести это поведение с помощью этого кода в консоли:

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

Таким образом, различие, которое вы видели, связано с (а) синхронностью заполнения массивов.

1 голос
/ 17 апреля 2019

Вато, у вас есть две функции в вашем сервисе: 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 получил массив наблюдаемых и, в подписке, получил ответ в массиве

//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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...