refer :

https://github.com/angular/angular/issues/10929

https://stackoverflow.com/questions/41280471/how-to-implement-routereusestrategy-shoulddetach-for-specific-routes-in-angular

一切从这个开始.

刚开始接触 SPA 的朋友们可能会很不习惯 scroll position 在游览器后退的时候并不会智能的滚动回之前页面的位置.

这时就会出现上面这张图片的需求了.

我个人认为, 做 SPA 交互设计就不要走回跳转页面的老套路线. 应该寻求创新而不是模拟从前的功能.

不过现实就是, 创新不出来..只能走老路...哈哈

下面来聊聊模拟的技术.

我们知道 SPA 是通过 history.push 来替换游览器地址的,然后通过路由器匹配出组件, 在渲染和替换页面.

即使是游览器后退也是通过监听 onpopstate, 然后匹配路由, 渲染组件...

所以整个过程都被 javascript l拦截处理了,游览器基本上什么也干不了.  (从前游览器会在 url 替换时 scroll to top, 在后退时 scroll to 之前的位置)

那么我们就得替代游览器工作了.

首先建一个全局的滚动条.

在前进时要 scroll to top, 我们可以拦截 router change 事件,然后 scrollTop = 0

在后退时, 我们要恢复位置就必须做记入.

那么我们在 router change 时, 把当前的 scrollTop 记入起来.

这样就行了.

呃... 哪有这么容易...

游览器后退的时候, 其实是使用之前的缓存资料的, 所以你会感觉它渲染很快马上就回滚到位了.

但 SPA 每一次都会从新渲染页面, 组件初始化-> ajax -> 渲染 -> 这时候你才可以滚动到之前的位置..

来, 介绍 angular 的 RouteReuseStrategy !

这个东西可以让组件所有 state 和渲染好的 html 被存起来. 然后快速的调出来用.

no more 组件初始化-> ajax -> 渲染.

export declare abstract class RouteReuseStrategy {
abstract shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean;
abstract shouldAttach(route: ActivatedRouteSnapshot): boolean;
abstract retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null;
abstract shouldDetach(route: ActivatedRouteSnapshot): boolean;
abstract store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle | null): void;
}

这个是它的类,我们继承然后替换掉 provider 就可以被 angular 调用了.

angular 会在每一次 router change 的时候调用它.

angular 路由就是棵树, 当 url 从 a/b/c/d 切换到 a/e/f/g 时.

shouldReuseRoute 会被触发. angular 会让你去对比看是否要 reuse

a vs a

b vs e

c vs f

d vs g

一般情况下 a vs a 自然时 reuse

b vs e 就替换, 而一旦 parent 被替换, 那么所有 child 自然也是被替换的

替换一旦发生, 就会有某些组件要被丢弃 destroy, 这时 shouldDetech, store 就会被调用, 用于缓存这些已经渲染完成即将被丢弃的组件.

有组件被丢弃自然有组件需要进来替补, 而这时 shouldAttach,retrieve 就会被调用, 用来调出缓存的组件.

所以流程是这样 :

1. 是否替换 ?

2. 替换发生, 有组件离去, 有组件加入

3. 离去的组件, 我们可以缓存

4. 加入的组件, 我们可以使用缓存好的组件.

替换->缓存->重用 就是整体的核心了.

Angular 学习笔记 (路由外传 - RouteReuseStrategy)的更多相关文章

  1. Angular学习笔记—路由(转载)

    创建路由 1.首先安装 Angular Router.你可以通过运行以下任一操作来执行此操作: yarn add @angular/router # OR npm i --save @angular/ ...

  2. angular学习笔记(三十一)-$location(2)

    之前已经介绍了$location服务的基本用法:angular学习笔记(三十一)-$location(1). 这篇是上一篇的进阶,介绍$location的配置,兼容各版本浏览器,等. *注意,这里介绍 ...

  3. angular学习笔记(三十一)-$location(1)

    本篇介绍angular中的$location服务的基本用法,下一篇介绍它的复杂的用法. $location服务的主要作用是用于获取当前url以及改变当前的url,并且存入历史记录. 一. 获取url的 ...

  4. angular学习笔记(三十)-指令(10)-require和controller

    本篇介绍指令的最后两个属性,require和controller 当一个指令需要和父元素指令进行通信的时候,它们就会用到这两个属性,什么意思还是要看栗子: html: <outer‐direct ...

  5. angular学习笔记(三十)-指令(7)-compile和link(2)

    继续上一篇:angular学习笔记(三十)-指令(7)-compile和link(1) 上一篇讲了compile函数的基本概念,接下来详细讲解compile和link的执行顺序. 看一段三个指令嵌套的 ...

  6. angular学习笔记(三十)-指令(7)-compile和link(1)

    这篇主要讲解指令中的compile,以及它和link的微妙的关系. link函数在之前已经讲过了,而compile函数,它和link函数是不能共存的,如果定义了compile属性又定义link属性,那 ...

  7. angular学习笔记(三十)-指令(6)-transclude()方法(又称linker()方法)-模拟ng-repeat指令

    在angular学习笔记(三十)-指令(4)-transclude文章的末尾提到了,如果在指令中需要反复使用被嵌套的那一坨,需要使用transclude()方法. 在angular学习笔记(三十)-指 ...

  8. angular学习笔记(三十)-指令(5)-link

    这篇主要介绍angular指令中的link属性: link:function(scope,iEle,iAttrs,ctrl,linker){ .... } link属性值为一个函数,这个函数有五个参数 ...

  9. angular学习笔记(三十)-指令(2)-restrice,replace,template

    本篇主要讲解指令中的 restrict属性, replace属性, template属性 这三个属性 一. restrict: 字符串.定义指令在视图中的使用方式,一共有四种使用方式: 1. 元素: ...

  10. angular学习笔记(三十)-指令(1)-概述

    之前在 angular学习笔记(十九)-指令修改dom 里面已经简单的提到了angular中的指令,现在来详细的介绍 '指令' 一.指令的创建: dirAppModule.directive('dir ...

随机推荐

  1. 【Unity与23种设计模式】抽象工厂模式(Abstract Factory)

    GoF中定义: "提供一个能够建立整个类群组或有关联的对象,而不必指明它们的具体类." 意思就是 根据不同的执行环境产生不同的抽象类子类 抽象工厂模式经常在面试中会涉及到 下面的例 ...

  2. JVM内存越多,能创建的线程越少,越容易发生java.lang.OutOfMemoryError: unable to create new native thread。

    一.认识问题: 首先我们通过下面这个 测试程序 来认识这个问题:运行的环境 (有必要说明一下,不同环境会有不同的结果):32位 Windows XP,Sun JDK 1.6.0_18, eclipse ...

  3. Docker国内镜像源设置

    编辑json文件,添加如下内容后重启docker即可. [root@Docker ~]# cat /etc/docker/daemon.json{ "registry-mirrors&quo ...

  4. xampp配置多端口访问

    1.修改D:\xampp\apache\conf\extra中的httpd-vhosts.conf文件,在最底部添加 <VirtualHost *:8080> ##需要监听的端口号 Ser ...

  5. Maven-06: 插件的内置绑定

    Maven的生命周期与插件相互绑定,用以完成实际的构建任务.具体而言,是生命周期的阶段与插件的目标相互绑定,以完成某个具体的构建任务.例如项目编译这一任务,它对应default生命周期的compile ...

  6. Webpack的加载器

    一.什么是加载器(loaders)loaders 用于转换应用程序的资源文件,他们是运行在nodejs下的函数 使用参数来获取一个资源的来源并且返回一个新的来源(资源的位置),例如:你可以使用load ...

  7. Tomcat 开启Gzip压缩

    原理简介         HTTP 压缩可以大大提高浏览网站的速度,它的原理是,在客户端请求服务器对应资源后,从服务器端将资源文件压缩,再输出到客户端,由客户端的浏览器负责解压缩并浏览.相对于普通的浏 ...

  8. c++ --> union介绍

    union介绍 共用体,也叫联合体,在一个“联合”内可以定义多种不同的数据类型, 一个被说明为该“联合”类型的变量中,允许装入该“联合”所定义的任何一种数据,这些数据共享同一段内存,以达到节省空间的目 ...

  9. 0x00-Kali Linux 系列入门篇

    Kali Linux介绍篇 Kali Linux 官网:https://www.kali.org/ Kali Linux 前身是著名渗透测试系统BackTrack ,是一个基于 Debian 的 Li ...

  10. 发布利用 Qt Assistant来做帮助系统的程序遇到的问题

    最近,一直在做反演初始模型可视化建模的软件 model Constraint,最后的步骤就是利用 Qt Assistant为自己的程序制作帮助系统. 1.<Qt Creator快速入门>和 ...