使用 Angular Material DataTable 时 Angular 组件的 ngOnInit 中的 SetTimeOut 函数
SetTimeOut function inside ngOnInit of Angular component while using Angular Material DataTable
我正在检查我现有项目之一的 Angular 代码,并在下面的代码片段中找到。
我们正在使用 Angular material datatable
在页面上呈现视图
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()
returns 只要 HttpResponse
可用,Observable
和 subscribe
就会被异步调用,
setTimeout
函数内部的操作是否会在 仅在 调用 subscribe
方法之后被调用?
2) 我看到 ngAfterViewInit
方法也包含与 ngOnInit
方法
中的 setTimeout
方法完全相同的代码
3) 但是当这个方法被调用时 (ngAfterViewInit)
, this.products
仍然是 NULL 表明订阅还没有被调用 '
4) 这就是在 ngOnInit
方法中调用 setTimeout
的原因吗?
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!");
}
此代码的输出将是:
world!Hello,
但是为什么呢?
那是因为 observable
模式。
你可以想象当你和两个人一起走路时:一个懂英语,一个不懂英语。因此,即使您先对不懂英语的人说 "How are you?",他也需要时间来理解您说的内容并回答您。同时,另一个人(非常懂英语)立即回答你。
functionA
和functionB
的例子是一样的。 FunctionA only 在订阅捕获到某些东西时执行。这就是为什么它不首先被解雇的原因。可以看到这里放了一个调试点:
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);
}
先执行哪个函数?
剧透:你不可能知道的。
如果您想知道为什么,这很简单:您确切知道函数 B 将在 500 毫秒后调用,但您无法知道需要多少时间使用订阅才能准备就绪。所以如果你运气好,你的订阅通常需要500ms左右才能完成,你可以尝试重新加载页面几次,有时你会看到Hello, world!
,有时你会看到world!Hello,
.
为了更好地回答您的问题:我真的不知道您为什么要这样放置代码,完全不知道。
ngAfterViewInit 是 life-cycle
在 ngOnInit 之后调用,并在 Angular 完全初始化组件视图后执行逻辑。
我会尽量简化描述:
setTimeout 将内部函数放在 javascript 队列的末尾,因此当 javascript 进程为 运行 时,它将从堆栈中弹出并调用手术。只有当堆栈为空时,队列中的任何内容才会被调用。所以 setTimeout
告诉 javascript 保留这段代码直到你完成你的工作。
subscribe 和 observable:observable 是异步数据结构,所以一旦你订阅了它,你就永远不知道调用订阅方法需要多少时间。换句话说,仅当示例 http 响应 returns.
时才会调用订阅
回到你的问题:你不知道你的 setTimeout 代码什么时候被调用,但理论上它会在订阅之前被调用(javascript 引擎比 http 响应更快)。
如果你需要初始化一些数据 table 结构,只有在你从 http 请求中获取数据后,你应该把它放在 subscribe
方法中,而不需要 setTimeout。
ngAfterViewInit
被 angular 用来告诉开发者,在这个阶段你的 view
已经准备好了,你可以作为例子使用 elementRef.
ngOnInit
被 angular 用来告诉开发者所有的输入和指令...等
1. 否,setTimeout 将仅在订阅之前被调用一次,因为它在其上下文之外。
2. 因为异步更新,如果我们异步更新属性,当验证循环为 运行 时,值将不会更新,我们不会收到错误。
3.ViewChild只有在ngAfterViewInit之后才可用。它会在创建视图时填充子项,因此它们可以更早地使用。
4. ngOnInit 生命周期挂钩在 DOM 更新操作之前触发,不会给出错误。 ngOnInit 生命周期挂钩在处理完绑定后触发。 ngAfterViewInit 在最初呈现视图时调用,即在创建组件视图及其子视图后调用。
5. ngAfterViewInit() 应该在组件的视图及其子视图创建之后调用,最重要的是子视图的 ngAfterViewInit() 在父视图的 ngAfterViewInit( ).
我正在检查我现有项目之一的 Angular 代码,并在下面的代码片段中找到。
我们正在使用 Angular material datatable
在页面上呈现视图
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()
returns 只要 HttpResponse
可用,Observable
和 subscribe
就会被异步调用,
setTimeout
函数内部的操作是否会在 仅在 调用 subscribe
方法之后被调用?
2) 我看到 ngAfterViewInit
方法也包含与 ngOnInit
方法
setTimeout
方法完全相同的代码
3) 但是当这个方法被调用时 (ngAfterViewInit)
, this.products
仍然是 NULL 表明订阅还没有被调用 '
4) 这就是在 ngOnInit
方法中调用 setTimeout
的原因吗?
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!");
}
此代码的输出将是:
world!Hello,
但是为什么呢?
那是因为 observable
模式。
你可以想象当你和两个人一起走路时:一个懂英语,一个不懂英语。因此,即使您先对不懂英语的人说 "How are you?",他也需要时间来理解您说的内容并回答您。同时,另一个人(非常懂英语)立即回答你。
functionA
和functionB
的例子是一样的。 FunctionA only 在订阅捕获到某些东西时执行。这就是为什么它不首先被解雇的原因。可以看到这里放了一个调试点:
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);
}
先执行哪个函数?
剧透:你不可能知道的。
如果您想知道为什么,这很简单:您确切知道函数 B 将在 500 毫秒后调用,但您无法知道需要多少时间使用订阅才能准备就绪。所以如果你运气好,你的订阅通常需要500ms左右才能完成,你可以尝试重新加载页面几次,有时你会看到Hello, world!
,有时你会看到world!Hello,
.
为了更好地回答您的问题:我真的不知道您为什么要这样放置代码,完全不知道。
ngAfterViewInit 是 life-cycle
在 ngOnInit 之后调用,并在 Angular 完全初始化组件视图后执行逻辑。
我会尽量简化描述:
setTimeout 将内部函数放在 javascript 队列的末尾,因此当 javascript 进程为 运行 时,它将从堆栈中弹出并调用手术。只有当堆栈为空时,队列中的任何内容才会被调用。所以
setTimeout
告诉 javascript 保留这段代码直到你完成你的工作。subscribe 和 observable:observable 是异步数据结构,所以一旦你订阅了它,你就永远不知道调用订阅方法需要多少时间。换句话说,仅当示例 http 响应 returns.
时才会调用订阅
回到你的问题:你不知道你的 setTimeout 代码什么时候被调用,但理论上它会在订阅之前被调用(javascript 引擎比 http 响应更快)。
如果你需要初始化一些数据 table 结构,只有在你从 http 请求中获取数据后,你应该把它放在 subscribe
方法中,而不需要 setTimeout。
ngAfterViewInit
被 angular 用来告诉开发者,在这个阶段你的 view
已经准备好了,你可以作为例子使用 elementRef.
ngOnInit
被 angular 用来告诉开发者所有的输入和指令...等
1. 否,setTimeout 将仅在订阅之前被调用一次,因为它在其上下文之外。
2. 因为异步更新,如果我们异步更新属性,当验证循环为 运行 时,值将不会更新,我们不会收到错误。
3.ViewChild只有在ngAfterViewInit之后才可用。它会在创建视图时填充子项,因此它们可以更早地使用。
4. ngOnInit 生命周期挂钩在 DOM 更新操作之前触发,不会给出错误。 ngOnInit 生命周期挂钩在处理完绑定后触发。 ngAfterViewInit 在最初呈现视图时调用,即在创建组件视图及其子视图后调用。
5. ngAfterViewInit() 应该在组件的视图及其子视图创建之后调用,最重要的是子视图的 ngAfterViewInit() 在父视图的 ngAfterViewInit( ).