AngularJS项目开发技巧之利用Service&Promise&Resolve解决图片预加载问题(后记)

举报
SHQ5785 发表于 2024/02/28 09:04:22 2024/02/28
【摘要】 前言      在“AngularJS项目开发技巧之图片预加载”一文中,自己曾经天真的认为提升服务端带宽就可以解决图片加载问题。但自己的想法错了,通过阅读破狼的书《AngularJS深度剖析与最佳实践》,隐隐察觉到是自己的项目架构出现了问题。存在很多待优化的地方。其书中这样写到“如果在实例化控制器之前,需要准备一些特定数据,或者有条件的阻止进入路由,那么可以在$routeProvider中配...

前言

      在“AngularJS项目开发技巧之图片预加载”一文中,自己曾经天真的认为提升服务端带宽就可以解决图片加载问题。但自己的想法错了,通过阅读破狼的书《AngularJS深度剖析与最佳实践》,隐隐察觉到是自己的项目架构出现了问题。存在很多待优化的地方。其书中这样写到“如果在实例化控制器之前,需要准备一些特定数据,或者有条件的阻止进入路由,那么可以在$routeProvider中配置Resolve属性来解决。”

注:预载入Resolve

      使用预载入功能,开发者可以预先载入一系列依赖或者数据,然后注入到控制器中。在ngRoute中resolve选项可以允许开发者在路由到达前载入数据保证(promises)。在使用这个选项时比使用angular-route有更大的自由度。

      预载入选项需要一个对象,这个对象的key即要注入到控制器的依赖,这个对象的value为需要被载入的factory服务。

      如果传入的是字符串,angular-route会试图匹配已经注册的服务。如果传入的是函数,该函数将会被注入,并且该函数返回的值便是控制器的依赖之一。如果该函数返回一个数据保证(promise),这个数据保证将在控制器被实例化前被预先载入并且数据会被注入到控制器中。

思路

      将图片下载耗时操作做异步处理。图片下载代码如下:

try {
var data = {};
appCallServer($http, "9101", data,
//success function
function(data) {
console.log("9101:" + JSON.stringify(data.data));
var adpic = new Array;
for (var i = 0; i < data.data.length; i++) {
adpic[i] = data.data[i].url;
}
$scope.adpic = adpic;
return true;
},
// fail function
function(data) {
$ionicLoading.show({
template: "查询广告失败,请检查您的网络连接"
});
$timeout(function() {
$ionicLoading.hide();
}, 1200);
return false;
});
} catch (error) {
$scope.showAlert1("call:" + error.message);
return false;
}

整理后的代码如下:

控制器:

$scope.getadpic = function() {
$scope.adpic = adpic;
};
$scope.getadpic();

执行程序,查看效果,提示如下错误:

 

unpr全称是Unknown Provider,也就是说没有找到注入的东西。

找了半天忽然醒悟了,resolve中的对象只有在相应的控制器中才可以获取到,而自己之前是在别的控制器中添加的resolve对象,难怪总是报服务未注入的错误呢。正确的代码如下:

路由:

$stateProvider
.state('tab', {
url: "/tab",
templateUrl: "tabs.html",
controller: 'tabsCtrl',
resolve:{
adpic:function(){
return "www";
}
}
})

控制器:

myCtrl.controller('tabsCtrl'function($scope$rootScope$http$location,... $timeoutadpic) {

...

$scope.getadpic function() {

console.log("adpic.........." adpic);

};


$scope.getadpic();

}

所以一定要掌握原理。不要茫然。

添加以上代码后,HBuilder报如下错误:


通过参考网络文献,优化后的代码如下:

// 利用Factory单例特性创建服务
myModule.factory('myAdpicService',function($http, $q){
 
return {
getAdpic: function() {
var d = $q.defer();
var data = {};
appCallServer($http, "9101", data,
//success function
function(data) {
console.log("9101_resolve:" + JSON.stringify(data.data));
var adpic = new Array;
for (var i = 0; i < data.data.length; i++) {
adpic[i] = data.data[i].url;
}
console.log("adpic___________:" + adpic);
d.resolve(adpic);
},
// fail function
function(data) {
$ionicLoading.show({
template: "查询广告失败,请检查您的网络连接"
});
$timeout(function() {
$ionicLoading.hide();
}, 1200);
d.reject(data);
});
return d.promise;
}
}
});<span style="color: rgb(62, 75, 83); font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>
<span style="color:#ff0000;">$stateProvider
.state('tab', {
url: "/tab",
templateUrl: "tabs.html",
controller: 'tabsCtrl',
resolve:{
adpicSunny:function(myAdpicService) {
       return myAdpicService.getAdpic();
}
    }
}</span>

      控制器中的代码不做任何变化。

代码回顾

      以上代码通过定义一个独立的service的方式来使用resolve key,并且使用service来相应返回所需的数据(这种方式更容易测试)。并且对于较耗时的图片加载操作做异步处理。这与Android中的设计思想一致。至此,图片预加载问题成功解决。

有图有真相

 

参考文献

1.www.bkjia.com-官网首页

2.http://www.bubuko.com/infodetail-828239.html

3.AngularJS 防止页面闪烁的方法 - I have a dream. - OSCHINA - 中文开源技术交流社区

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。