几乎所有新手开始学习angular时, 接触到的第一个例子都是双向数据绑定, 紧跟着就是如何使用angular去发一个AJAX请求, 看起来十分简单粗暴.
$http.post('/products', product).success(function(createdProduct) {
// w00t!
});
如果你不了解JS中的Promise, 阅读阮一峰Promise, 当然Promise并不是这篇文章的大前提, 你只需要知道, .success()和.error()方法都是angular特有的, 普通的promise对象只有.then().
.success()怎么坑了我
也不能说.success()坑了我, 应该是我自己把自己埋到了坑里, 最近公司的angular项目重构, 采用component base 的结构, angular1.5升级到1.6. 跑起来之后有一个第三方插件报错.
TypeError: $http(...).success is not a function
这还不简单? 找到压缩过的代码, 想当然的把success换成了then. 报错没了. 哈哈哈!!! 诶? 等等... 好像哪里不太对的样子, 数据怎么拿不到了.
// We need now to set the image and audio field names
if (response.audioFieldName) {
config.audioFieldName = response.audioFieldName;
}
if (response.imageFieldName) {
config.imageFieldName = response.imageFieldName;
}
response里的数据都没了. 清一色的undefined. 好吧. 这才发现success()并不是简单的then()函数的第一个参数. 还有其他的猫腻.
.success()如何实现
在angular源码中, success的实现基本如下
promise.success = function(fn) {
// ...
promise.then(function(response) {
fn(response.data, response.status, response.headers, config);
});
return promise;
};
所以它并没有什么, 只是then()的一个语法糖. 解构了response. 把response.data作为第一个参数给返回了, 由于拦截器里返回的数据都在response.data里, 所以直接在response上取, 得到的是undefined.
这下豁然开朗了, 修复这个问题自然不在话下咯, 为了插件对低版本的项目的兼容, 做了如下处理.
if (response.data) {
response = response.data;
}
写代码还是不能自己感觉该这么写, 该那么写, 该看文档还是得看文档!