Angular 2+中setTimeout的替代方法

7

我正在将数据发送到ngrx store。之后,我想要滚动到一个特定的div,该div正在使用来自store的数据。

@ViewChild('datalist') private myScrollContainer: ElementRef; 

this.store.dispatch(new SetClientSearchResultsAction(filteredData));

setTimeout(() => {
this.myScrollContainer.nativeElement.scrollIntoView({ behavior:'smooth', block: 'start'});
 }, 300);

以下是HTML的div块。
<div  #datalist id="mydata" *ngIf="clientSearchResults$ | async  as searchResults" 
class = 'result'>
  <p> hellooo</p>
</div>

在将数据分配到存储中后,我会在我的 div 中获取滚动条。但我不想使用 setTimeout ,因为这样做是 不必要的等待300毫秒。有没有其他的 替代方法? 我只想在分配数据或ngif条件得到满足时滚动到我的 div

下面是我的组件构造函数,在其中我从Store中获取值。

constructor(private store: Store<AppState>,
    private formBuilder: FormBuilder, private _clientService: ClientService) {
    this.clientSearchResults$ = this.store.select('searchResults');
  }

值得一提的是,scrollIntoView 是一个实验性功能,不被所有浏览器支持。https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView。请参阅所提供链接的浏览器兼容性。 - amu
3个回答

2
您可以使用生命周期钩子AfterViewInit。它会在Angular初始化组件的视图和子视图/指令所在的视图之后进行响应,保留HTML标签。
class MyComponent implements AfterViewInit {
  ngAfterViewInit() {
    // ...
  }
}

但是,我必须将滚动设置为div,这会影响我使用afterview init还是init。 - Nimish goel

0

使用RXJS有多种方式。

选项1 - 使用asapScheduler

asapScheduler.schedule(() => { // Your Code });

链接

选项2 - 使用间隔

import { interval } from 'rxjs';
import { take } from 'rxjs/operators';

  interval(0).pipe(take(1),
   ).subscribe(value => { // Your Code });

链接

选项3 - 使用Promise

Promise.resolve().then(() => { // Your Code });

最佳方式是使用选项1,因为它旨在避免setTimeout(deferredTask, 0)

从RxJS文档中了解到asapScheduler:

asap调度程序将尽其所能缩短当前执行代码结束和计划任务开始之间的时间。这使得它成为执行所谓的“延迟”操作的最佳选择。传统上,这是通过调用setTimeout(deferredTask, 0)来实现的,但这种技术涉及一些(虽然很小)不必要的延迟。


-2
假设在调度SetClientSearchResultsAction时,clientSearchResults$将发出新值,您可以在组件中订阅clientSearchResults$并从那里启动滚动。
ngOnInit() {
  clientSearchResults$
  .subscribe(() => {
    this.myScrollContainer.nativeElement.scrollIntoView({ behavior:'smooth', block: 'start'});
  });
}

我已经添加了构造函数代码,其中我正在设置clientSearchResults$中的值。现在,您能告诉我需要做哪些更改吗? - Nimish goel
我也尝试过这件事,在订阅中,如果我不使用settimeout,它就无法工作。而当我加入setTimeout后,我就能滚动到我的div了。 - Nimish goel
1
尝试像Rahul Sharma建议的那样将其放在ngAfterViewInit中。 - amu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接