外部函数后不在 [ ] 内的对象的打字稿数组

typescript array of objects not inside [ ] after outside function

我尝试根据 Angular 中打字稿中的数据进行分组,以显示在 table

我的问题是,当我在 GroupDataForShowIntable() 函数中控制日志对象数组时,它看起来不错,但是当我在 ngOnInit() 中控制日志对象数组时,它在 [][=13= 之外]

import { Component, OnInit} from '@angular/core';
import { DirectiveService } from '../services/directive.service';

const groupBy = function (xs, key) {
  return xs.reduce(function (rv, x) {
    (rv[x[key]] = rv[x[key]] || []).push(x);
    return rv;
  }, {});
};

@Component({
  selector: 'app-my-directive',
  templateUrl: './my-directive.component.html',
  styleUrls: ['./my-directive.component.css']
})


export class MyDirectiveComponent implements OnInit {

  constructor(private directiveService: DirectiveService) { }
  
  dataSource = [];
  displayedColumns: string[];

  GroupDataForShowIntable() {
    //getdata From Backend API
    this.directiveService.GetMyDirectiveList().subscribe(response => {
      if (response['operation'] == 'success') {
        const data = response['data'];
        var new_data = groupBy(data, 'directive_topic');
        Object.keys(new_data).filter(key => {
          this.dataSource.push({ directive_topics: key, isGroupBy: true });
          let values = new_data[key];
          values.filter((element) => { this.dataSource.push(element); });
        });
        console.log('InSideFunction', this.dataSource)
      }
    }, (err) => {
      console.log('fail', err);
    }, () => {
      console.log('success');
    });
  }

  ngOnInit(): void {
    this.GroupDataForShowIntable()
    console.log('OutSideFunction', this.dataSource)
    this.displayedColumns = ['directive_group_name_text', 'directive_committee_position'];
  }

  isGroup(index, item): boolean {
    return item.isGroupBy
  }

}

我不明白为什么请帮忙

我希望对象数组进入内部 []

似乎更像是异步时间问题。

 dataSource = [];
displayedColumns: string[];

//flag that can be used in ngIf in template
isDataTableComplete: false; 

GroupDataForShowIntable() {
//getdata From Backend API
this.directiveService.GetMyDirectiveList().subscribe(response => {
  if (response['operation'] == 'success') {
    const data = response['data'];
    var new_data = groupBy(data, 'directive_topic');
    Object.keys(new_data).filter(key => {
      this.dataSource.push({ directive_topics: key, isGroupBy: true });
      let values = new_data[key];
      values.filter((element) => { this.dataSource.push(element); });
    });
    //Table is shown only after the entire computation is done
    this.isDataTableComplete = true; 
    console.log('InSideFunction', this.dataSource)
  }
}, (err) => {
  console.log('fail', err);
}, () => {
  console.log('success');
});
}

数据不在数组之外,这只是调试器执行 lazy-loading 的副作用。当您在 ngOnInit 中记录数组时,该数组是空的,但是当您在调试器中单击下拉列表时,该数组已被异步 subscribe 回调填充。

当您在函数中记录数据时,您在填充数组后将其记录在 subscribe 回调中。所以当然在你登录的时候它已经被填满了。

当您单击 drop-down 时,您的调试器将引用数组并获取元素。因此,如果自初始日志以来数组已更改,您将看到第一行与实际内容不匹配。


根据您的评论,问题是您没有看到 html 更新。这是因为将新对象推入数组不会导致触发更改检测,这只会在您重新分配整个数组时发生。使用 ChangeDetectorRef 服务强制更改检测。

  constructor(
    private directiveService: DirectiveService,
    private changeDetectorRef: ChangeDetectorRef
  ) {}

  GroupDataForShowIntable() {
    //getdata From Backend API
    this.directiveService.GetMyDirectiveList().subscribe(response => {
      if (response['operation'] == 'success') {
        const data = response['data'];
        var new_data = groupBy(data, 'directive_topic');
        Object.keys(new_data).filter(key => {
          this.dataSource.push({ directive_topics: key, isGroupBy: true });
          let values = new_data[key];
          values.filter((element) => { this.dataSource.push(element); });
        });
        this.changeDetectorRef.detectChanges();
        console.log('InSideFunction', this.dataSource)
      }
    }, (err) => {
      console.log('fail', err);
    }, () => {
      console.log('success');
    });
  }