下面这种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对象的更多相关文章

  1. angular学习笔记(二十八-附1)-$resource中的资源的方法

    通过$resource获取到的资源,或者是通过$resource实例化的资源,资源本身就拥有了一些方法,$save,$delete,$remove,可以直接调用来保存该资源: 比如有一个$resour ...

  2. angular学习笔记(二十八)-$http(6)-使用ngResource模块构建RESTful架构

    ngResource模块是angular专门为RESTful架构而设计的一个模块,它提供了'$resource'模块,$resource模块是基于$http的一个封装.下面来看看它的详细用法 1.引入 ...

  3. angular学习笔记(二十九)-$q服务

    angular中的$q是用来处理异步的(主要当然是http交互啦~). $q采用的是promise式的异步编程.什么是promise异步编程呢? 异步编程最重要的核心就是回调,因为有回调函数,所以才构 ...

  4. Java学习笔记二十八:Java中的接口

    Java中的接口 一:Java的接口: 接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明.一个类通过继承接口的方式,从而来继承 ...

  5. Java基础学习笔记二十八 管家婆综合项目

    本项目为JAVA基础综合项目,主要包括: 熟练View层.Service层.Dao层之间的方法相互调用操作.熟练dbutils操作数据库表完成增删改查. 项目功能分析 查询账务 多条件组合查询账务 添 ...

  6. angular学习笔记(二十六)-$http(4)-设置请求超时

    本篇主要讲解$http(config)的config中的timeout项: $http({ timeout: number }) 数值,从发出请求开始计算,等待的毫秒数,超过这个数还没有响应,则返回错 ...

  7. angular学习笔记(二十五)-$http(3)-转换请求和响应格式

    本篇主要讲解$http(config)的config中的tranformRequest项和transformResponse项 1. transformRequest: $http({ transfo ...

  8. angular学习笔记(二十四)-$http(2)-设置http请求头

    1. angular默认的请求头: 其中,Accept 和 X-Requested-With是$http自带的默认配置 Accept:application/json,text/plain       ...

  9. angular学习笔记(二十二)-$http.post

    基本语法: $http.post('url',{},{}).success(function(data,status,headers,config){ }).error(function(data,s ...

随机推荐

  1. JavaScript 解决 onblur 与 onclick 冲突

    <input type="text" onblur="function1" /> <input type="button" ...

  2. 深入理解Spring--动手实现一个简单的SpringIOC容器

    接触Spring快半年了,前段时间刚用Spring4+S2H4做完了自己的毕设,但是很明显感觉对Spring尤其是IOC容器的实现原理理解的不到位,说白了,就是仅仅停留在会用的阶段,有一颗想读源码的心 ...

  3. Introduction of python

    "Life is short, you need Python!" Python (British pronunciation:/ˈpaɪθən/ American pronunc ...

  4. Spark 入门

    Spark 入门 目录 一. 1. 2. 3. 二. 三. 1. 2. 3. (1) (2) (3) 4. 5. 四. 1. 2. 3. 4. 5. 五.         Spark Shell使用 ...

  5. 「译」JUnit 5 系列:架构体系

    原文地址:http://blog.codefx.org/design/architecture/junit-5-architecture/ 原文日期:29, Mar, 2016 译文首发:Linesh ...

  6. 在Ubuntu|CentOS上安装Shutter截图工具及快捷键设置

    简介 Shutter前身叫GScrot,它是一款相当棒的截图软件. 通过Shutter,你可以截取包括选定区域.全屏幕.窗口.窗口内的控件甚至网页的图像.通过内置的强大插件机制,你可以在截图后,对图像 ...

  7. C#开机自动启动程序代码

    新建一个winform拖一个checkbox进来.. 然后设置它的changed事件. 已经测试过,可以直接复制使用. private void checkBox1_CheckedChanged(ob ...

  8. 使用PublishSetting快速在Powershell中登录Azure

    使用Powershell 来管理Azure资源实在是一大快事. 在使用power script之前, 需要先连接到Azure上,其中使用导入PublishSetting文件是最方便的方法. 步骤: 1 ...

  9. Servlet3.0的异步

    servlet之前的操作同时同步的,就是按照这样的一个流程来走的: 1.请求根据一个路径路由到一个servlet中, 2.servlet获取一系列的参数 3.执行一系列的逻辑(花费时间所占的比重也更大 ...

  10. Windows10应用Docker部署DoNet Core

    Win10和Mac稳定版的Docker发布了,之前看了下徐磊老师的几篇Docker4Dotnet的文章http://devopshub.cn/2016/07/08/docker4dotnet-1-ov ...