angular学习笔记(二十八-附2)-$http,$resource中的promise对象
下面这种promise的用法,我从第一篇$http笔记到$resource笔记中,一直都有用到:
HttpREST.factory('cardResource',function($resource){
    return $resource('/card/user/:userID/:id',{userID:123,id:'@id'},{charge:{method:'POST',params:{charge:true},isArray:false}})
});
HttpREST.factory('httpCard',function($q,cardResource){
    return {
        getById:function(cardID){
            var defer = $q.defer();
            cardResource.get({id:cardID},function(data,headers){
                defer.resolve(data);
            },function(data,headers){
                defer.reject(data);
            });
            return defer.promise
        }
    }
});
$scope.card_1 = httpCard.getById(1);
  <span>{{card_1['name']}}</span>
  <span>{{card_1['amount']}}</span>
这样做的目的很显然,由于后台返回数据需要时间,所以对card_1的赋值应该是异步的,所以getById方法返回的是一个promise,所以,card_1其实也是一个promise,我们把它打印出来可以看到:
1.同步打印:(还不等到后台返回数据就打印)
$scope.card_1 = httpCard.getById(1);
console.log($scope.card_1);

2.异步打印:(等到后台返回数据以后打印)
$scope.card_1 = httpCard.getById(1);
$scope.card_1.then(function(){console.log($scope.card_1)});

可以看到,同步打印的card_1,它的$$v是undefined,因为后台还没有返回数据,但异步打印的card_1,它的$$v就是请求后返回的数据.
问题就出现了,card_1只有一个$$v属性和一个then方法,它并没有name属性,也没有amount属性,但是在视图中,<span>{{card_1['name']}}</span>确实渲染了.虽然我没有看过源代码,但是可以推测,视图渲染card_1的时候,是使用了card_1的$$v对象来进行渲染的.所以访问card_1['name'],其实是访问了card_1的$$v['name'].
那么,如果card_1发生变化的时候,又是怎么处理的呢? 我尝试了以下操作:
$scope.updataCard = function(){
  $scope.card_1.name='工商银行';    //视图不会发生变化
  $scope.card_1.$save()            //card_1没有$save方法
};
发现直接操作card_1.name属性,虽然card_1的name属性确实发生了变化,但是,在视图中它并没有任何的变化.可见,视图对于promise对象,监测的依然是它的$$v对象的属性的变化,而它自己的属性变化是没有任何反应的.另外,card_1是promise对象,不是$resource返回的对象,card_1的$$v才是,所以,card_1当然也没有$save方法
那么,如果我要更新card_1,修改card_1,到底应该怎么做的? 说到底,card_1的真身就是card_1的$$v对象,so,想要修改card_1,就要修改它的$$v对象:
$scope.updataCard = function(){
  $scope.card_1.$$v.name='工商银行';
  $scope.card_1.$$v.$save();
};
这样做,视图就会被更新.但是这样做有一个问题,上面已经看到了,$$v对象是在请求已经得到响应,得到返回的数据的时候才有的,在没有得到响应前,$$v是undefined.所以,如果在还没有得到响应前就执行了updataCard函数,这段代码就会有问题.so,最好的方法是放在promise的then方法的回调函数的参数里:
    $scope.updataCard = function(){
        $scope.card_1.then(function(data){
            data.name='工商银行';
            data.$save()
        });
    };
promise对象有一个then方法,then方法了接受三个回调,详细参考:http://www.cnblogs.com/liulangmao/p/3907571.html ,这里只写一个成功的回调,回调的参数data,也就是promise对象的$$v对象,then函数会在响应成功后被调用.所以,即便还没有得到响应就触发了updataCard方法,修改的操作还是会等到响应收到后才执行,这就是异步.
注意,这里的card_1是直接通过$resource返回得到的promise,但如果是通过angular路由的resolve方法返回的对象,在resolve的时候已经取了promise对象的$$v对象,然后再注入到控制器中.这样得到的资源就不再是promise对象了,而已经是promise的$$v对象,后面都正常操作就可以了.
angular学习笔记(二十八-附2)-$http,$resource中的promise对象的更多相关文章
- angular学习笔记(二十八-附1)-$resource中的资源的方法
		
通过$resource获取到的资源,或者是通过$resource实例化的资源,资源本身就拥有了一些方法,$save,$delete,$remove,可以直接调用来保存该资源: 比如有一个$resour ...
 - angular学习笔记(二十八)-$http(6)-使用ngResource模块构建RESTful架构
		
ngResource模块是angular专门为RESTful架构而设计的一个模块,它提供了'$resource'模块,$resource模块是基于$http的一个封装.下面来看看它的详细用法 1.引入 ...
 - angular学习笔记(二十九)-$q服务
		
angular中的$q是用来处理异步的(主要当然是http交互啦~). $q采用的是promise式的异步编程.什么是promise异步编程呢? 异步编程最重要的核心就是回调,因为有回调函数,所以才构 ...
 - Java学习笔记二十八:Java中的接口
		
Java中的接口 一:Java的接口: 接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明.一个类通过继承接口的方式,从而来继承 ...
 - Java基础学习笔记二十八 管家婆综合项目
		
本项目为JAVA基础综合项目,主要包括: 熟练View层.Service层.Dao层之间的方法相互调用操作.熟练dbutils操作数据库表完成增删改查. 项目功能分析 查询账务 多条件组合查询账务 添 ...
 - angular学习笔记(二十六)-$http(4)-设置请求超时
		
本篇主要讲解$http(config)的config中的timeout项: $http({ timeout: number }) 数值,从发出请求开始计算,等待的毫秒数,超过这个数还没有响应,则返回错 ...
 - angular学习笔记(二十五)-$http(3)-转换请求和响应格式
		
本篇主要讲解$http(config)的config中的tranformRequest项和transformResponse项 1. transformRequest: $http({ transfo ...
 - angular学习笔记(二十四)-$http(2)-设置http请求头
		
1. angular默认的请求头: 其中,Accept 和 X-Requested-With是$http自带的默认配置 Accept:application/json,text/plain ...
 - angular学习笔记(二十二)-$http.post
		
基本语法: $http.post('url',{},{}).success(function(data,status,headers,config){ }).error(function(data,s ...
 
随机推荐
- php-resque的设计和使用
			
php-resque-1.2-annotated 一个 php-resque 源码阅读的项目,欢迎大家star php-resque的设计 在Resque中,一个后台任务被抽象为由三种角色共同完成: ...
 - spring aop
			
什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将 ...
 - 【分布式】Zookeeper客户端
			
一.前言 前篇博客分析了Zookeeper的序列化和通信协议,接着继续学习客户端,客户端是开发人员使用Zookeeper最主要的途径,很有必要弄懂客户端是如何与服务端通信的. 二.客户端 2.1 客户 ...
 - c#编程基础之字符串函数
			
c#常用的字符串函数 例一: 获取字符串的大小写函数 ToLower():得到字符串的小写形式 ToUpper():得到字符串的大写形式 注意: 字符串时不可变的,所以这些函数都不会直接改变字符串的内 ...
 - [Spring]04_最小化Spring XML配置
			
4.1 自动装配 Bean Spring 装配 bean 时,有时非常明确,就是需要将某个 bean 的引用装配给指定属性. 例如,若应用上下文中只有一个 javax.sql.DataSource 类 ...
 - 周末惊魂:因struts2 016 017 019漏洞被入侵,修复。
			
入侵(暴风雨前的宁静) 下午阳光甚好,想趁着安静的周末静下心来写写代码.刚过一个小时,3点左右,客服MM找我,告知客户都在说平台登录不了(我们有专门的客户qq群).看了下数据库连接数,正常.登录阿里云 ...
 - 使用java泛型设计通用方法
			
泛型是Java SE 1.5的新特性, 泛型的本质是参数化类型, 也就是说所操作的数据类型被指定为一个参数. 因此我们可以利用泛型和反射来设计一些通用方法. 现在有2张表, 一张user表和一张stu ...
 - tomcat 504 gateway time-out
			
今天有个环境ajax调用一个请求的时候,出现一个504 gateway time-out响应,原以为是nginx找不到资源的问题,恰当我们的服务器上又配置了nginx,看了配置文件,没有指向tomca ...
 - Django简介和安装
			
Django 最开源地方就是可以使用强大第三方插件1,Django默认没有提供对象(Object)级别的权限控制,我们可以通过该Django Guardian 扩展来帮助Django实现对象级别的权限 ...
 - ViewPager之Fragment页面切换
			
一.概述 ViewPager是android-support-v4中提供的类,它是一个容器类,常用于页面之间的切换. 继上篇文章<ViewPager之引导页>之后,本文主要介绍ViewPa ...