我在我现有的一个项目中查看了一段 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()
返回 Observable
和subscribe
每当 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
模式。
您可以想象一下,当您与两个人同行时:一个懂英语,一个不懂英语。所以即使你说“你好吗?”首先对于不懂英语的人来说,他需要时间来理解你说什么并回答你。与此同时,另一个人(非常懂英语)会立即回答你。
functionA
和 functionB
的示例是相同的。 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/