Angular 跨页缓存设计
发布时间:2020-12-17 10:07:47 所属栏目:安全 来源:网络整理
导读:自去年开始,AngularJS 引入到项目中,并逐渐推动公司产品核心模块进行重构,提升产品稳定性与开发效率。在前端架构演进的过程中最艰难的不是理解 API,而是思维方式被颠覆的无助,所有繁杂的事务都被高度抽象化,以前 WEB 富 UI 开发最头疼的表现部分放到现
自去年开始,AngularJS 引入到项目中,并逐渐推动公司产品核心模块进行重构,提升产品稳定性与开发效率。在前端架构演进的过程中最艰难的不是理解 API,而是思维方式被颠覆的无助,所有繁杂的事务都被高度抽象化,以前 WEB 富 UI 开发最头疼的表现部分放到现在几乎不费吹灰之力,前端工程师重心将由 UI 转向数据模型的构建。在这个过程中,小伙伴经常会遇到跨页数据传递这个经典问题,于是我在公司给组里同事做了一次分享,以下是概要: 业务场景
问题
可选方案A. 超级单页使用同一个控制器与同一份实例,不使用路由 缺点
B. URL传递数据通过 URL 查询参数传递数据 缺点
D. Ng Service 缓存使用 Angular Service 构建内存缓存 权衡后,采用此方案。 实践遇到的问题唯一性难以保证
内存泄露
基于路由缓存设计保证唯一性
cacheKey// 取 URL 的 cache key var cacheKey = $routeParams['cache_key']; 读写缓存 if (!AppCache.cache || AppCache.key !== cacheKey) { // 覆盖 service 缓存 AppCache.cache = createCache(); AppCache.key = cacheKey || Date.now().toString(); } 发送缓存 // 通过路由传递缓存 $scope.submit = function () { var queryParam = angular.extend({ 'cache_key': AppCache.key },$routeParams); $location.search(queryParam); } 解决内存泄露
清理过期缓存 $rootScope.$on('$routeChangeSuccess',function () { if ($routeParams['cache_key'] === undefined) { AppCache.cache = {}; } }) 封装 RouteCache 服务高度抽象,屏蔽实现细节 API 设计(第一版)// 读缓存 var routeCache = RouteCache(createCache); var data = routeCache.getCache(); var cacheKey = routeCache.getKey(); // 通过路由传递缓存 $scope.submit = function () { var queryParam = angular.extend({ 'cache_key': cacheKey },$routeParams); $location.search(queryParam); } API 设计(优化后)// 读缓存 var data = RouteCache(createCache); // 通过路由传递缓存 $scope.submit = function () { var queryParam = angular .extend({},data,$routeParams); $location.search(queryParam); } 问题:如何做到 URL 只显示 cache_key 而不暴露数据? 答案:使用原型继承,angular.extend 不会拷贝原型。 RouteCache 内部: data = createCache(); data = Object.create(data); data['cache_key'] = cacheKey;
Object.create = function (object) { function F(){}; F.prototype = object; return new F(); } RouteCache 服务完整源码/* * 基于路由的缓存服务 * 可以将任何数据模型缓存在路由参数中,适合处理跨页的数据传递 * * 取缓存: * $scope.data = RouteCache(cacheFactory); * 写缓存: * $location.search( * angular.extend( * {},* $routeParams,* $scope.data * ) * ); * * @author 糖饼 */ define(['./services'],function (services) { services.factory('RouteCache',['$rootScope','$routeParams','$cacheFactory',function ($rootScope,$routeParams,$cacheFactory) { var cache = $cacheFactory('RouteCache'); var ROUTE_KEY = '@cache_key'; var TABLE_NAME = 'CACHE'; /* * @param {Function} 缓存工厂 * @return {Object} 继承自缓存的对象 */ function Cache (cacheFactory) { var data = cache.get(TABLE_NAME); var routeKey = $routeParams[ROUTE_KEY]; if (!data || cache.get(ROUTE_KEY) !== routeKey) { data = cacheFactory(); // 继承缓存 data = Object.create(data); cache.put(TABLE_NAME,data); cache.put(ROUTE_KEY,routeKey || Date.now().toString()); } data[ROUTE_KEY] = cache.get(ROUTE_KEY); return data; }; // 自动清理缓存 $rootScope.$on('$routeChangeSuccess',function () { if (typeof $routeParams[ROUTE_KEY] === 'undefined') { cache.removeAll(); } }); return Cache; }]); }); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |