I am dispatching the data to ngrx store. After that I want to scroll to a specific div
, which is using this data from store.
@ViewChild('datalist') private myScrollContainer: ElementRef;
this.store.dispatch(new SetClientSearchResultsAction(filteredData));
setTimeout(() => {
this.myScrollContainer.nativeElement.scrollIntoView({ behavior:'smooth', block: 'start'});
}, 300);
Below is the HTML div.
<div #datalist id="mydata" *ngIf="clientSearchResults$ | async as searchResults"
class = 'result'>
<p> hellooo</p>
</div>
I am getting the scroll at my div after dispatching the data to store. But I do not want to use setTimeout
. It is unnecessarily waiting for 300 milliseconds. Is there any alternative way to do that ? I just want to scroll to my div
, when my data is dispatched or ngif condition got fulfilled.
Below is the constructor of my ponent where I am getting the value from Store.
constructor(private store: Store<AppState>,
private formBuilder: FormBuilder, private _clientService: ClientService) {
this.clientSearchResults$ = this.store.select('searchResults');
}
I am dispatching the data to ngrx store. After that I want to scroll to a specific div
, which is using this data from store.
@ViewChild('datalist') private myScrollContainer: ElementRef;
this.store.dispatch(new SetClientSearchResultsAction(filteredData));
setTimeout(() => {
this.myScrollContainer.nativeElement.scrollIntoView({ behavior:'smooth', block: 'start'});
}, 300);
Below is the HTML div.
<div #datalist id="mydata" *ngIf="clientSearchResults$ | async as searchResults"
class = 'result'>
<p> hellooo</p>
</div>
I am getting the scroll at my div after dispatching the data to store. But I do not want to use setTimeout
. It is unnecessarily waiting for 300 milliseconds. Is there any alternative way to do that ? I just want to scroll to my div
, when my data is dispatched or ngif condition got fulfilled.
Below is the constructor of my ponent where I am getting the value from Store.
constructor(private store: Store<AppState>,
private formBuilder: FormBuilder, private _clientService: ClientService) {
this.clientSearchResults$ = this.store.select('searchResults');
}
Share
Improve this question
edited Apr 3, 2018 at 9:40
Nimish goel
asked Apr 3, 2018 at 9:16
Nimish goelNimish goel
2,7716 gold badges30 silver badges42 bronze badges
1
-
It is worth mentioning that
scrollIntoView
is an experimental feature not supported by all browsers. developer.mozilla/en-US/docs/Web/API/Element/scrollIntoView. See the Browser patibility of the provided link. – amu Commented Apr 3, 2018 at 10:59
3 Answers
Reset to default 2You can use Lifecycle hook, AfterViewInit
Respond after Angular initializes the ponent's views and child views / the view that a directive is in.
class MyComponent implements AfterViewInit {
ngAfterViewInit() {
// ...
}
}
There are multiple ways with RXJS
Option 1 - with asapScheduler
asapScheduler.schedule(() => { // Your Code });
Link
Option 2 - with interval
import { interval } from 'rxjs';
import { take } from 'rxjs/operators';
interval(0).pipe(take(1),
).subscribe(value => { // Your Code });
Link
Option 3 - With Promise
Promise.resolve().then(() => { // Your Code });
The Optimum way will be with Option 1 as it is made to avoid setTimeout(deferredTask, 0)
From the RxJS docs for asapScheduler
:
asap scheduler will do its best to minimize time between end of currently executing code and start of scheduled task. This makes it best candidate for performing so called "deferring". Traditionally this was achieved by calling setTimeout(deferredTask, 0), but that technique involves some (although minimal) unwanted delay.
Assuming that clientSearchResults$
will emit a new value when dispatching SetClientSearchResultsAction
, you can subscribe to clientSearchResults$
in your ponent and initiate the scrolling from there.
ngOnInit() {
clientSearchResults$
.subscribe(() => {
this.myScrollContainer.nativeElement.scrollIntoView({ behavior:'smooth', block: 'start'});
});
}