javascript - 使用 Angular Material 数据表时,Angular 组件的 ngOnInit 内的 SetTimeOut 函数

标签 javascript angular angular-material settimeout

我在我现有的一个项目中查看了一段 Angular 代码,并发现了下面的代码片段。 我们正在使用Angular material datatable在页面上呈现 View

export class Component implements OnInit,AfterViewInit{

  private dataSource: MatTableDataSource<Product> = null;
  @ViewChild(MatPaginator) paginator: MatPaginator; 

  columnsToDisplay = ['productId','productname'];
  constructor(private _service : DataService) { }

  ngOnInit() {

    this._service.getProducts().subscribe(
     ((data : Product[]) => this.dataSource = new MatTableDataSource(data)),
     () => console.log('THIS IS ERROR')
    );
    setTimeout(() => this.dataSource.paginator = this.paginator);
    //this.dataSource.paginator = this.paginator;
  }

  ngAfterViewInit() {
    this.dataSource.paginator = this.paginator; 
  }

}

我的问题是:

1) 自 this.service.getData()返回 Observablesubscribe每当 HttpResponse 时都会被异步调用可用 , 在 setTimeout 内进行操作函数将仅在subscribe之后调用方法被称为?

2) 我已经看到 ngAfterViewInit方法还包含与 setTimeout 中完全相同的代码ngOnInit中的方法方法

3) 但是当调用这个方法时(ngAfterViewInit) , this.products仍然为 NULL 表明 subscribe 尚未被调用 '

4) 是这个原因吗setTimeout里面调用ngOnInit方法 ?

5)如果是这样的话ngAfterViewInit有什么用呢?方法 ?

最佳答案

1)这取决于。订阅仅在操作完成时才执行代码。因此,当 this.service.getData() 完成其工作时。 setTimeout 在延迟后完成工作。如果订阅需要的时间小于setTimeout,则会先执行。

2)也许您想注意函数何时执行?

3) AfterViewInit 被多次触发。您可以像这样检查 if(!!something) 然后执行一些代码。

4)您应该始终避免使用settimeout(仅将其用于调试目的)。

编辑:

ngOnInit() {

this._service.getProducts().subscribe(
 ((data : Product[]) => this.dataSource = new MatTableDataSource(data)),
 () => console.log('THIS IS ERROR')
);
setTimeout(() => this.dataSource.paginator = this.paginator);
//this.dataSource.paginator = this.paginator;

} `

让我们简单介绍一下这段代码:

ngOnInit() {
  this.service.doStuff()
  .subscribe(result => {
    this.functionA();
  },
  err => {
    //Do other stuff in case of an error
  });

  this.functionB();
}

functionA(){
  console.log("Hello,");
}

functionB(){
  console.log("world!");
}

此代码的输出将是:

世界!你好,

但是为什么呢?

这是因为 observable 模式。

您可以想象一下,当您与两个人同行时:一个懂英语,一个不懂英语。所以即使你说“你好吗?”首先对于不懂英语的人来说,他需要时间来理解你说什么并回答你。与此同时,另一个人(非常懂英语)会立即回答你。

functionAfunctionB 的示例是相同的。 FunctionA 在订阅捕获到某些内容时执行。这就是为什么它不首先被解雇的原因。您可以看到在这里放置了一个调试点:

ngOnInit() {
      this.service.doStuff()
      .subscribe(result => {
      --->  this.functionA();
      },
      err => {
        //Do other stuff in case of an error
      });

      --->  this.functionB();
    }

希望能够很好地解释这一点。

现在让我们继续,让我们使用超时:

 ngOnInit() {
          this.service.doStuff()
          .subscribe(result => {
            this.functionA();
          },
          err => {
            //Do other stuff in case of an error
          });

          settimeout(() => {
            this.functionB();
          }, 500);
        }

哪个函数会先执行?

剧透:你不可能知道这一点。

如果你想知道为什么,很简单:你确切地知道 functionB 将在 500ms 后被调用,但你无法知道订阅需要多少时间才能准备好。所以如果你幸运的话,你的订阅通常需要500ms左右才能完成,你可以尝试重新加载页面几次,有时你会看到 Hello, world!,有时你会看到 world !你好,

为了更好地回答你的问题:我真的不知道你为什么要这样写代码,真的不知道。

ngAfterViewInit 是一个在 ngOnInit 之后调用的生命周期,在 Angular 完全初始化组件 View 后执行逻辑。

关于javascript - 使用 Angular Material 数据表时,Angular 组件的 ngOnInit 内的 SetTimeOut 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52479205/

相关文章:

Javascript 内存泄漏 : why would assigning object to null work?

javascript - 如何使用 PHP 处理 Controller 的 XMLhttp 请求

html - 如何在 Safari 浏览器中显示 Angular Material 垫选择中的滚动条?

javascript - 如何使用函数更改使用 JSON 的响应?

javascript - AngularJS Material 将元素推送到页面右侧

javascript - 是否有调试 jQuery 事件处理程序的工具/技术?

javascript - UIWebView - 加载带有链接资源的本地 .html 文件

angular - 从 Ionic 2 更新到 Ionic 3,现在由于 "Unexpected token {"错误而无法构建

http.get 不要打电话,Angular 2

Angular Material Datepicker - nextClicked,previousClicked 不发射