angularjs数据存储
① 怎样操作angularjs缓存
这次给大家带来怎样操作angularjs缓存,操作angularjs缓存的注意事项有哪些,下面就是实战案例,一起来看一下。
一、什么是缓存
一个缓雀衫存就顷仔腔是一个组件,它可以透明地存储数据,以便未来可以更快地服务于请求。
缓存能够服务的请求越多,整体系统性能就提升得越多。
二、Angular 中的缓存
2.1 $cacheFactory 简介
$cacheFactory 是一个为所有Angular服务生成缓存对象的服务。在内部, $cacheFactory 会创建一个默认的缓存对象,即使我们并没有显示地创建。
要创建一个缓存对象,可以使用 $cacheFactory 通过一个ID创建一个缓存:
var cache = $cacheFactory('myCache');
这个 $cacheFactory 方法可以接受两个参数:
cacheId (字符串):这个 cacheId 就是创建缓存时的ID名称。可以通过 get() 方法使用缓存名称来引用它。
capacity :这个容量描述了在任何给定时间要使用缓存存储并保存的缓存键值对的最大数量。
2.2 缓存对象
缓存对象自身有下列这些方法可以用来与缓存交互。
info() : info() 方法返回缓存对象的ID、尺寸和选项。
put() : put() 方法允许我们把任意javaScript对象值形式的键(字符串)放进缓存中。cache.put("hello","world");
put() 方法会返回我们放入缓存中的值。
get() : get() 方法让我们能够访问一个键对应的缓存值。如果找到了这个键,它会返回它的值;如果没有找到,它会返回 undefined 。cache.get("hello");
remove() : remove() 函数用于在找到一个键值对的情况下从缓存中移除它。如果没有找到,它就会返回 undefined 。cache.remove("hello");
removeAll() : removeAll() 函数用于重置缓存,同时移除所有已缓存的值。
destory() : destory() 方法用于从 $cacheFactory 缓存注册表中移除指定缓存的所有引用。
三、$http 中的缓存
Angular的 $http 服务创建了一个带有ID为 $http 的缓存。 要让 $http 请求使用默认的缓存 对象很简单: $http() 方法允许我们给它传递一个 cache 参数。
3.1 默认的 $http 缓存
当数据不会经常改变时,默认的 $http 缓存就特别有用了。可以像这样设置它:
$http({
method: 'GET',
url: '/api/users.json',
cache: true//设置为true只是用来使用$http默认的缓存机制
});现在,通过 $http 到URL /api/user.json 的每个请求将会存储到默认的 $http 缓存中。 这个$http 缓存中的请求键就是完整的URL路径。
如果需要,也可以操作这个默认的 $http 缓存(比如,如果我们发起的另外一个没有缓存的请求提醒我们发生了增量变化,我们就可以在默认的 $http 请戚握求中清除这个请求)。
为了引用 $http 的默认请求,只需通过 $cacheFactory() 使用ID来获取到该缓存:
var cache = $cacheFactory('$http');对于所掌控的缓存,我们可以在需要时进行所有的正常操作,比如检索已缓存的响应,从缓存中清除条目,或者消除所有缓存的引用。
// 获取上一次请求的缓存
var usersCache = cache.get('http://example.com/api.users.json');
// 删除上一次请求的缓存入口
cache.remove('http://example.com/api.users.json');
// 重新开始并移除全部缓存
cache.removeAll(); var cache = $cacheFactory.get('$http');
if(cache.get('cacheData')){
console.log(cache.get('cacheData'));
}else{
helloService.play().then(
function (data) {
cache.put("cacheData", data);//往缓存中放入数据
console.log(data);
}
);
}3.2 自定义缓存
有时候能够对缓存有更多的控制以及针对缓存的表现创建规则,这就需要创建一个新的缓存来使用 $http 请求。
通过自定义的缓存来让 $http 请求发起请求很简单。可以采用传递缓存实例的方式,而不必传递一个布尔参数 true 给请求。
var myCache = $cacheFactory('myCache');
$http({
method: 'GET',
utl: '/api/users.json',
cache: myCache
});一个小demo:定义一个缓存服务,依赖注入到你要用的控制器中,直接使用
define([
'angularMole'
],function(app){
app.factory('myCache', ['$cacheFactory', function($cacheFactory){
return $cacheFactory('myCache'); //自定义一个缓存服务
}])
}); //自定义缓存,有缓存就从缓存里取,否则就发送请求
if(myCache.get('cacheData')){
console.log(myCache.get('cacheData'));
}else{
helloService.play(myCache).then(
function (data) {
myCache.put("cacheData", data);
console.log(data);
}
);
}
cache:只是为了可以使用默认$http的缓存机制
play : function (myCache) {
return httpRequestService.request({
method : 'get',
url : 'http://localhost:8080/hello/play',
cache : myCache
})
}现在, $http 将会使用自定义的缓存而非默认缓存。
四、为 $http 设置默认缓存
每次我们想要发起一个 $http 请求时都要给它传递一个缓存实例并不方便,特别是对每个请求使用同一缓存的时候。
其实可以在模块的 .config() 方法中通过 $httpProvider 设置 $http 默认使用的缓存对象。
angular.mole('myApp', []).config(function($httpProvider) {
$httpProvider.defaults.cache = $cacheFactory('myCache', {capacity: 20});
});这个 $http 服务不再使用它为我们创建的默认缓存;它会使用我们自定义的缓存,实际上这就是一个近期缓存最久未使用算法① (Least Recently Used,LRU)。
LRU缓存根据缓存容量只保留最新的缓存数目。也就是说,我们的缓存容量为20,因此会缓存前20个请求,但是进入第21个请求时,最近最少使用的请求条目就会从缓存中被删除。这个缓存自身会负责具体哪些要维护,哪些要移除。
相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!
推荐阅读:
jquery+fullpage添加界面内的头部与版权
如何使用webpack+vue环境局域网
② angularjs window.localstorage存储的数据任何controller都可以读取吗
ocalStorage存储方法 localStorage.name = localStorage["name"]='vanida';localStorage.setItem("name","vanida");//这三种设置值方式是一样的; localStorage获取值方法 var name = localStorage["name"] = localStorage.name= localStorage...
③ 在anjular中 function中的$scope和$rootscope有什么区别
scope是angularJS中的作用域(其实就是存储数据的地方),很类似javascript的原型链。搜索的时型哗候,优先找自己的scope,如果没有找到就沿着作用域链向上搜索,直至到达根作用域rootScope。
$rootScope是由angularJS加载模块的时候自动创建的,每个模块只会有1个rootScope。rootScope创建好会以服务的形式加入到$injector中。也就是说通过$injector.get("$rootScope");能够获取到某个模块的根作用域。更准确的来说,$rootScope是由angularJS的核心模块ng创建的。
scope是html和单个controller之间的桥梁,数据绑定就靠他了。rootscope是各个controller中scope的桥梁。用rootscope定义的值,可以在各个controller中使用
示例1:
//新建一个模块
varmole=angular.mole("app",[]);
//true说明$rootScope确实以服务的形式包含在模块的injector中
varhasNgInjector=angular.injector(['app','ng']);
console.log("has$rootScope="+hasNgInjector.has("$rootScope"));//true
//获取模块相应的injector对象,不获取ng模块中的服务
//不依赖于ng模块,无法获取$rootScope服务
varnoNgInjector=angular.injector(['app']);
console.log("no卜册行$rootScope="+noNgInjector.has("$rootScope"));//false
//获取angular核心的ng模块
varngInjector=angular.injector(['ng']);
console.log("ng$rootScope="+ngInjector.has("$rootScope"));//true
上面的代码的确可以说明:$rootScope的确是由核心模块ng创建的,并以服务的形式存在于injector中。
如果创建injector的时候,指定了ng模块,那么该injector中就会包含$rootScope服务;否则就不包含$rootScope。
示例2:
<!doctypehtml>
<htmllang="en">
<head>
<metacharset="utf-8">
<scriptsrc="angular-1.2.25.js"></script>
<script>
varmole=angular.mole("app",[]);
//控制器里的$injector,是由angular框架自动创建的
functionFirstController($scope,$injector,$rootScope)
{
$rootScope.name="aty";
}
//自己创建了个injector,依赖于app和ng模块
varmyInjector=angular.injector(["app","ng"]);
varrootScope=myInjector.get("$rootScope");
alert(rootScope.name);//udefined
</script>
</head>
姿渣<bodyng-app="app">
<divid="first"ng-controller="FirstController">
<inputtype="text"ng-model="name">
<br>
{{name}}
</div>
</body>
</html>
angular.injector()可以调用多次,每次都返回新建的injector对象。所以我们自己创建的myInjector和angular自动创建的$injector不是同一个对象,那么得到的rootScope也就不是同一个。
示例3:
<!doctypehtml>
<htmllang="en">
<head>
<scriptsrc="angular-1.2.25.js"></script>
<script>
functionFirstController($scope,$injector,$rootScope)
{
//true
console.log("scopeparent:"+($scope.$parent==$rootScope));
}
</script>
</head>
<bodyng-app>
<divid="first"ng-controller="FirstController">
<inputtype="text"ng-model="name">
<br>
{{name}}
</div>
</body>
</html>
ng-controller指令给所在的DOM元素创建了一个新的$scope对象,并作为rootScope的子作用域。$scope是由$rootScope创建的,$scope不会保护在$injector中。
示例4:
<!doctypehtml>
<htmllang="en">
<head>
<metacharset="utf-8">
<title>scope()</title>
<scriptsrc="jquery-1.11.1.js"></script>
<scriptsrc="angular-1.2.25.js"></script>
<script>
//记住rootScope,用来判断跨控制器是否相等
varfirst_rootScope=null;
//记住scope,用来判断跨控制器是否相等
varfirst_scope=null;
//记住injector,用来判断跨控制器是否相等
varfirst_injectot=null;
//第1个angular控制器
functionFirstController($scope,$injector,$rootScope)
{
$rootScope.name="aty";
first_rootScope=$rootScope;
first_injectot=$injector;
first_scope=$scope;
}
//第2个angular控制器,主要是来测试跨controller时injector和scope的表现
functionSecondController($scope,$injector,$rootScope)
{
console.log("first_rootScope==second_rootScope:"+(first_rootScope==$rootScope));//true
console.log("first_injectot==second_injector:"+(first_injectot==$injector));//true
console.log("first_scope==second_scope:"+(first_scope==$scope));//false
}
</script>
</head>
<bodyng-app>
<divid="first"ng-controller="FirstController">
<inputtype="text"ng-model="name">
<br>
<divid="tips"></div>
</div>
<h2>outsideofcontroller</h2>
<br>
<!--访问每一个应用(模块)的rootScope-->
{{$root.name}}
<divid="noControllerDiv"/>
<divng-controller="SecondController">
</div>
</body>
</html>
ng-app定义了一个angular模块,每个模块只有一个$rootScope,只有一个$injector,但可以有多个$scope。
弄清了$injector、$rootScope和$scope这3者之间的关系,我们看下angular提供的2个API,一个是scope(),一个是injector()。使用angular.element()返回的DOM对象,都会包含这2个方法,用来获取与之关联的scope和injector。
由于每个模块的injector是唯一的,所以angular.element().injector()直接返回元素所在模块的injector。
angular.element().scope()可以获取到当前元素的scope或父scope。如果当前元素有scope,则返回自己的scope;如果没有则向父亲方向寻找,如果找不到返回rootScope。即返回作用域链上,距离该元素最近的scope。
<!doctypehtml>
<htmllang="en">
<head>
<metacharset="utf-8">
<title>scope()</title>
<scriptsrc="jquery-1.11.1.js"></script>
<scriptsrc="angular-1.2.25.js"></script>
<script>
functionFirstController($scope,$injector,$rootScope)
{
//获取body对象
vardomBody=document.getElementsByTagName('body')[0];
//通过ng-app指令所在的DOM元素获取rootScope
varrtScope=angular.element(domBody).scope();
//当前元素没有新作用域,获取父作用域即rootScope
varnoScope=angular.element("#noControllerDiv").scope();
//true
console.log("rtScope==noScope:"+(rtScope==noScope));
//ng-controller所在的元素,返回的scope
varscopeOnController=angular.element("#first").scope();
//ng-controller内部的元素返回所在的scope
varinController=angular.element("#tips").scope();
//true
console.log("scopeOnController==inController:"+(scopeOnController==inController));
//验证通过DOM获取的scope是否与注入的$scope和$rootScope一致
//true
console.log("result1:"+(rtScope==$rootScope));
//true
console.log("result2:"+(inController==$scope));
}
</script>
</head>
<bodyng-app>
<divid="first"ng-controller="FirstController">
<inputtype="text"ng-model="name">
<br>
<divid="tips"></div>
</div>
<h2>outsideofcontroller</h2>
<br>
<!--访问每一个应用(模块)的rootScope-->
{{$root.name}}
<divid="noControllerDiv"/>
</body>
</html>