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. log4net应用实践(一)

          1.背景 log4net库是Apache log4j框架在Microsoft .NET平台的实现,是一个帮助程序员将日志信息输出到各种目标(控制台.文件.数据库等)的工具.它是.Net下一 ...

  2. IIS前端页面不显示详细错误解决方法

    要想解决这个问题,有三种方法可以考虑: 1.Internet信息服务(IIS)管理器 2.Web.config文件 3. 命令行 在IIS的"错误页"右边的"编辑功能设置 ...

  3. Unity3D打包 将发布的exe文件打包成一个Windows安装文件(自解压文件)

    Unity打包Standalone时 会出现一个exe文件和一个data文件夹 可是我们平常见过的软件 基本没有这种像这种结构的 一般都是一个安装文件,然后点击安装,选择路径,生成快捷方式- 本篇博客 ...

  4. 【Unity3D与23种设计模式】模板方法模式(Template Method)

    GoF中定义: "在一个操作方法中定义算法的流程,其中某些步骤由子类完成. 模板方法模式让子类在不变更原有算法流程的情况下,还能够重新定义其中的步骤" 每一次武器攻击目标时,都要按 ...

  5. postgresql和oracle数据库对比

    SQL执行计划干预 从使用postgresql来看,想要改变执行计划只能通过対表进行分析,不能通过添加hint的方式来改变执行计划: oracle不仅可以通过对表进行收集统计来改变执行计划,而且很重要 ...

  6. java--计时器

    计时器 一.窗口化 public class Pro extends JFrame{ private JTextField textField = new JTextField(45);//系统时间文 ...

  7. K-Means 聚类

    机器学习中的算法主要分为两类,一类是监督学习,监督学习顾名思义就是在学习的过程中有人监督,即对于每一个训练样本,有对应的标记指明它的类型.如识别算法的训练集中猫的图片,在训练之前会人工打上标签,告诉电 ...

  8. Mycat 安装与启动

    环境准备 安装JDK1.8(必须JDK1.7及更高版本) 安装MySQL 服务安装与说明 下载 MyCAT 编译好的安装包,下载地址为 http://dl.mycat.io/1.6-RELEASE/ ...

  9. 【Bootstrap】bootstrap-datetimepicker日期时间插件

    [bootstrap-datetimepicker] datetimepicker是一个比较方便的日期时间插件.有了这个之后,我们可以在类似于表单的地方提供一个友好的日期(时间)输入功能.官方文档:[ ...

  10. STL --> 高效使用STL

    高效使用STL 仅仅是个选择的问题,都是STL,可能写出来的效率相差几倍:
熟悉以下条款,高效的使用STL:   一.当对象很大时,建立指针的容器而不是对象的容器 1)STL基于拷贝的方式的来工作,任 ...