小说网站怎么做推广,asp网站的安全性,太原市手机网站建设,工业设计的就业前景这里给大家分享我在网上总结出来的一些知识#xff0c;希望对大家有所帮助 在切换详情页中有这么一个场景#xff0c;点击上一条#xff0c;会显示上一条的详情页#xff0c;同理#xff0c;点击下一条#xff0c;会显示下一条的详情页。 伪代码如下所示#xff1a; 我们… 这里给大家分享我在网上总结出来的一些知识希望对大家有所帮助 在切换详情页中有这么一个场景点击上一条会显示上一条的详情页同理点击下一条会显示下一条的详情页。 伪代码如下所示 我们定义了一个 switcher 模版 用户点击上一条、下一条时调用 goToPreOrNext 方法。该页面通过 loadingDone 状态判断是否展示加载效果。 // html
thy-loading [thyDone]loadingDone/thy-loading
ng-container *ngIfloadingDonestyx-pivot-detail...thy-arrow-switcher...(thyPrevious)goToPreOrNext($event)(thyNext)goToPreOrNext($event)/thy-arrow-switcher.../styx-pivot-detail
/ng-container在 goToPreOrNext 方法中当调用该方法时通过 goToPreOrNextResolve 接口返回下一条的详情 id通过该 id 请求详情数据。 // 请求下一条 id
fetchPreOrNext(event: ThyArrowSwitcherEvent) {...this.goToPreOrNextResolve(event.index, topicId).subscribe((id: string) {this.getDetail(id);}...)
}// 请求详情数据
getDetail(postId: string) {this.loadingDone false;this.store.fetchPost(postId).pipe(finalize(() {this.loadingDone true;})).subscribe();
}这看起来好像没有什么问题应该一般都是这么干的我们运行看看。 如何切换时候不闪 与最上面的相比有没有发现每次切换时都会闪一下用户体验很不好有没有办法可以解决它 这个问题就是 loadingDone 的状态切换导致的我们把 loadingDone 干掉是不是就可以了 如下代码所示: // 请求详情数据
getDetail(postId: string) {// 注释掉这一行// this.loadingDone false;this.store.fetchPost(postId).pipe(finalize(() {this.loadingDone true;})).subscribe();
}好像方案可行 但是把网络调成低速 3G 后会发现我们的加载效果没了页面像卡住了一样这当然不行。 有没有更好的方案 ⏰ setTimeout 方案 把先前 loadingDone 状态不放到 getDetail 方法中而是单独拿出来紧跟 this.getDetail(id) 后面。 代码如下 // 定义一个 timer
**private timer null;**// 请求下一条 id
fetchPreOrNext(event: ThyArrowSwitcherEvent) {...this.goToPreOrNextResolve(event.index, topicId).subscribe((id: string) {this.getDetail(id);**this.timer setTimeout(() {this.loadingDone false;}, 500);**}...)
}// 请求详情数据
getDetail(postId: string) {// 删除掉该行loadingDone 代码**// this.loadingDone false;**this.store.fetchPost(postId).pipe(finalize(() {this.loadingDone true;// 记得清除**clearTimeout(this.timer);**})).subscribe();
}这么做的含义就是我们给到 loadingDone 500ms 的缓冲时间如果 500ms 内返回数据了则没有 loading 的效果如果没有加载回来在会显示加载中。 一般情况如下所示 低速网络下的效果 这确实是一种方案但是总感觉哪里怪怪的。 这里是个定时任务并且 500ms 后触发。试想一种结果当我快速点击下一条并且在 300ms 获取到了数据并把 loadingDone 状态置为 true 但 500ms时loadingDone 状态置为 false造成假死的情况显然这不是我们想要的。 那这该如何解决 RxJS 大法 抛去使用 setTimeout 的方案我们对 getDetail 代码改成如下的形式。 大致的思路是将请求的 loading 状态与数据获取的状态分离并定义了两个流 result$ 和 showLoadingIndicator$。 result$ 流请求到数据之后之后之后的一些操作, showLoadingIndicator$ 流则负责 loading 状态的推送。 来看看怎么一步一步实现的 首先我们定义一个请求的流。 const fetchPost$ () this.store.fetchPost(postId);然后分别定义了两个流 result$ 和 showLoadingIndicator$。这里的 share() 函数是因为会有两个订阅它的地方。 const result$ fetchPost$().pipe(share());const showLoadingIndicator$;然后我们来处理 showLoadingIndicator$ 流。 我们期望在 500ms 内请求到的数据则不应该展示 loading否则应该展示 loading 状态。 const showLoadingIndicator$ timer(500).pipe(mapTo(true), takeUntil(result$))如果在 500ms 后很快请求到了数据为了避免闪屏我们需要让 loading 至少显示 1s。然后使用 merge() 合并这两种结果。 const showLoadingIndicator$ merge(timer(500).pipe(mapTo(true), takeUntil(result$)),combineLatest(result$, timer(1000)).pipe(mapTo(false))).pipe(startWith(false), distinctUntilChanged());最后订阅它们。 result$.subscribe(result {// 请求到结果后的操作},error {// TODO});showLoadingIndicator$.subscribe(isLoading {// 更新 loadingDone 状态this.loadingDone !isLoading;});完整的代码如下 // 请求下一条 id
fetchPreOrNext(event: ThyArrowSwitcherEvent) {...this.goToPreOrNextResolve(event.index, topicId).subscribe((id: string) {this.getDetail(id);}...)
}// 请求详情数据
getDetail(postId: string) {const fetchPost$ () this.store.fetchPost(postId);const result$ fetchPost$().pipe(share());const showLoadingIndicator$ merge(timer(500).pipe(mapTo(true), takeUntil(result$)),combineLatest(result$, timer(1000)).pipe(mapTo(false))).pipe(startWith(false), distinctUntilChanged());result$.subscribe(result {// TODO},error {// TODO});showLoadingIndicator$.subscribe(isLoading {this.loadingDone !isLoading;});
}如果想更细致知道如何实现的参考下面这篇文档 Loading indication with a delay and anti-flickering in RxJS 本文转载于: https://juejin.cn/post/7176943529057321017 如果对您有所帮助欢迎您点个关注我会定时更新技术文档大家一起讨论学习一起进步。