[nodejs,expressjs,angularjs2] LOL英雄列表数据抓取及查询显示应用
新手练习,尝试使用angularjs2
【angularjs2 数据绑定,监听数据变化自动修改相应dom值,非常方便好用,但与传统js(jquery)的使用方法会很不同,Dom操作也不太习惯】
应用效果图:
转载请标明出处:cnblogs.com/wangxinsheng
@望星辰
-----
具体步骤如下:
1.通过应用生成器工具 express 可以快速创建一个应用的骨架
全局安装 应用生成器工具:$ npm install express-generator -g
在当前工作目录下创建一个命名为 lolHeros 的应用:$ express lolHeros
2.添加并修改 package.json 配置文件,加入依赖
3.运行命令 npm install 安装依赖
4.启动这个应用
(MacOS 或 Linux 平台):$ DEBUG=lolHeros npm start
Windows 平台使用如下命令:set DEBUG=lolHeros & npm start
URL:http://127.0.0.1:3000/
5.应用生成器创建的应用一般都有如下目录结构:
.
├── app.js
├── bin
│ └── www
├── package.json
├── public
│ ├── images
│ ├── javascripts
│ └── stylesheets
│ └── style.css
├── routes
│ ├── index.js
│ └── users.js
└── views
├── error.jade
├── index.jade
└── layout.jade
7 directories, 9 files
6.使用supervisor
npm -g install supervisor
修改 package.json script 节点
node => supervisor
启动服务命令改为:npm start
7.选择性使用 html2jade
npm install -g html2jade
这里偷懒,用在线转换页面
8.先做一个html,看效果
9.用工具转为 jade 模板,看看nodejs 运行效果
http://www.html2jade.org/
10.做lol英雄数据抓取功能
轻量级应用,就不用DB了,用systemFile来替代DB功能
nodejs http抓取和文件读写操作,由于这次需要同步告知执行结果,就用了同步方法处理
http 同步模块使用 sync-request[npm install sync-request]
下载数据:1.英雄列表,2.英雄详细数据,3.英雄头像,4.皮肤,5.技能图标
11.最后,整合AngularJS2前端框架
package.json 中加入AngularJS依赖,npm install
注:npm下载插件速度慢时,可以使用阿里巴巴在国内的镜像服务器,命令如下:
npm install -gd express --registry=http://registry.npm.taobao.org
可以使用如下命令进行永久设置:
npm config set registry http://registry.npm.taobao.org
-----
关键代码如下:
依赖包 package.json:
1 { 2 "name": "lol_Heros", 3 "version": "1.0.0", 4 "description": "get and show lolHeros from qq with NodeJS-Server,ExpressJS-RouteAndTemplate,AngularJS2-JSFrontFramework,Bootstrap-CSS", 5 "private": true, 6 "keywords": [ 7 "lol", 8 "Heros" 9 ], 10 "author": "Wang Xinsheng", 11 "license": "MIT", 12 "scripts": { 13 "start": "tsc && concurrently \"tsc -w\" \"supervisor ./bin/www\" ", 14 "tsc": "tsc", 15 "tsc:w": "tsc -w" 16 }, 17 "dependencies": { 18 "@angular/common": "~2.4.0", 19 "@angular/compiler": "~2.4.0", 20 "@angular/core": "~2.4.0", 21 "@angular/forms": "~2.4.0", 22 "@angular/http": "~2.4.0", 23 "@angular/platform-browser": "~2.4.0", 24 "@angular/platform-browser-dynamic": "~2.4.0", 25 "@angular/router": "~3.4.0", 26 "@types/jquery": "^2.0.39", 27 "angular-in-memory-web-api": "~0.2.4", 28 "body-parser": "~1.15.2", 29 "cookie-parser": "~1.4.3", 30 "core-js": "^2.4.1", 31 "debug": "~2.2.0", 32 "express": "~4.14.0", 33 "jade": "~1.11.0", 34 "morgan": "~1.7.0", 35 "rxjs": "5.0.1", 36 "serve-favicon": "~2.3.0", 37 "sync-request": "~3.0.1", 38 "systemjs": "0.19.40", 39 "zone.js": "^0.7.4" 40 }, 41 "devDependencies": { 42 "concurrently": "^3.1.0", 43 "typescript": "~2.0.10", 44 "tslint": "^3.15.1", 45 "@types/node": "^6.0.46" 46 } 47 }
Express路由:省略,详细可查看附件
Nodejs 抓取数据代码(getHeroList.js):
1 /* GET Hreo List Data. */ 2 /*写入文件系统*/ 3 var fs= require('fs'); 4 var path = require('path'); 5 /*同步抓取*/ 6 var request = require('sync-request'); 7 8 // 所有英雄列表 9 var heroListPath = 'http://lol.qq.com/biz/hero/champion.js'; 10 // 单图 image full:http://ossweb-img.qq.com/images/lol/img/champion/Aatrox.png 11 var fullImgPath = 'http://ossweb-img.qq.com/images/lol/img/champion/'; 12 //英雄信息:Aatrox=data.ID.js 13 var heroDetailPath = 'http://lol.qq.com/biz/hero/'; 14 // skins.id http://ossweb-img.qq.com/images/lol/web201310/skin/big266000.jpg 15 var heroDetailSkinPath = 'http://ossweb-img.qq.com/images/lol/web201310/skin/big'; 16 // 技能:Aatrox_Passive.png=>http://ossweb-img.qq.com/images/lol/img/passive/Aatrox_Passive.png 17 var heroDetailPSkillPath = 'http://ossweb-img.qq.com/images/lol/img/passive/'; 18 // Q技能:http://ossweb-img.qq.com/images/lol/img/spell/AatroxQ.png Aatrox.png 19 var heroDetailSkillPath = 'http://ossweb-img.qq.com/images/lol/img/spell/'; 20 21 var heroVerPath = ''; 22 var heroVerSkinPath = ''; 23 var heroVerSkillPath = ''; 24 var heroVerImgPath = ''; 25 var heroListJson = null; 26 module.exports = function() { 27 console.log('GET Hreo List Data starting...'); 28 29 // 新建文件夹 30 // process.cwd() 启动目录 31 // process.execPath node.exe文件路劲 32 // __dirname 代码所在的目录 33 var heroDataPath = process.cwd() + '\\heroData'; 34 var exists = fs.existsSync(heroDataPath); 35 if(!exists){ 36 // 不存在创建目录 37 try{ 38 fs.mkdirSync(heroDataPath); 39 console.log('创建目录成功:'+heroDataPath); 40 }catch(e){ 41 console.log('创建目录失败',heroDataPath,e); 42 return '创建目录失败:'+'\n'+heroDataPath+'\n'+e; 43 } 44 } 45 // 抓取数据-所有英雄 46 var r = getHList(heroDataPath); 47 if(r!='') 48 return r; 49 // 抓取数据-所有英雄小头像 50 var r = getHListImg(); 51 if(r!=''){ 52 deleteFolderRecursive(heroVerPath); 53 return r; 54 } 55 console.log('GET Hreo List Data Finished'); 56 return ''; 57 }; 58 59 // 获取英雄列表,英雄版本重复检查,创建版本文件夹,写入英雄列表 60 function getHList(parentPath){ 61 console.log('GET Hreo List Data...'); 62 var opt = getRequireOption(heroListPath); 63 var res = request(opt.method,opt.path,opt); 64 var data = res.getBody("utf8"); 65 // jsonp 解析 66 data = data.replace('if(!LOLherojs)var LOLherojs={};LOLherojs.champion=',''); 67 data = data.substr(0 ,data.length-1); 68 data = reconvert(data); 69 heroListJson = JSON.parse(data); 70 console.log(heroListJson.version,heroListJson.updated); 71 //JSON.stringify(obj) 72 heroVerPath = parentPath + '\\'+heroListJson.version; 73 var exists = fs.existsSync(heroVerPath); 74 75 if(exists){ 76 console.log('存在该版本',heroListJson.version); 77 return '存在该版本'; 78 }else{ 79 try{ 80 fs.mkdirSync(heroVerPath); 81 }catch(e){ 82 console.log('创建目录失败',heroVerPath,e); 83 return '创建目录失败:'+"\n"+heroVerPath+"\n"+e; 84 } 85 86 var heroVerListPath = heroVerPath + '\\herolist.json'; 87 try{ 88 var w = fs.writeFileSync(heroVerListPath, JSON.stringify(heroListJson)); 89 }catch(e){ 90 console.log('写入错误',heroVerListPath,e); 91 return '写入错误:'+"\n"+heroVerListPath+"\n"+e; 92 } 93 console.log('写入成功',heroVerListPath); 94 } 95 console.log('GET Hreo List Data Finished'); 96 return ''; 97 } 98 99 function getHListImg(){ 100 // 抓取图片 101 // 创建头像目录 102 heroVerImgPath = heroVerPath + "\\" + "imgs"; 103 var exists = fs.existsSync(heroVerImgPath); 104 if(!exists){ 105 // 不存在创建目录 106 try{ 107 fs.mkdirSync(heroVerImgPath); 108 console.log('创建目录成功:'+heroVerImgPath); 109 }catch(e){ 110 console.log('创建目录失败',heroVerImgPath,e); 111 return '创建目录失败:'+'\n'+heroVerImgPath+'\n'+e; 112 } 113 } 114 // 皮肤目录 115 heroVerSkinPath = heroVerPath + "\\" + "skin"; 116 var exists = fs.existsSync(heroVerSkinPath); 117 if(!exists){ 118 // 不存在创建目录 119 try{ 120 fs.mkdirSync(heroVerSkinPath); 121 console.log('创建目录成功:'+heroVerSkinPath); 122 }catch(e){ 123 console.log('创建目录失败',heroVerSkinPath,e); 124 return '创建目录失败:'+'\n'+heroVerSkinPath+'\n'+e; 125 } 126 } 127 // 技能目录 128 heroVerSkillPath = heroVerPath + "\\" + "skill"; 129 var exists = fs.existsSync(heroVerSkillPath); 130 if(!exists){ 131 // 不存在创建目录 132 try{ 133 fs.mkdirSync(heroVerSkillPath); 134 console.log('创建目录成功:'+heroVerSkillPath); 135 }catch(e){ 136 console.log('创建目录失败',heroVerSkillPath,e); 137 return '创建目录失败:'+'\n'+heroVerSkillPath+'\n'+e; 138 } 139 } 140 for (var key in heroListJson.keys) { 141 // 下载头像图片 142 var imgName = heroListJson.data[heroListJson.keys[key]].image.full; 143 var fullImgUrl = fullImgPath+imgName; 144 console.log("抓取头像图片",imgName,fullImgUrl); 145 var opt = getRequireOption(fullImgUrl); 146 var res = request(opt.method,opt.path,opt); 147 var data = res.getBody(); 148 var heroVerFullImgPath = heroVerImgPath + '\\'+imgName; 149 try{ 150 var w = fs.writeFileSync(heroVerFullImgPath, data); 151 }catch(e){ 152 console.log('写入错误',heroVerFullImgPath,e); 153 return '写入错误:'+"\n"+heroVerFullImgPath+"\n"+e; 154 } 155 console.log('写入成功',heroVerFullImgPath); 156 157 // 下载英雄详细文件 158 var heroDataId = heroListJson.keys[key]; 159 var heroDataUrl = heroDetailPath+heroDataId+'.js'; 160 console.log("抓取英雄详细数据",heroDataId,heroDataUrl); 161 var opt = getRequireOption(heroDataUrl); 162 var res = request(opt.method,opt.path,opt); 163 var data = res.getBody('utf8'); 164 // jsonp 解析 165 data = data.replace('if(!LOLherojs)var LOLherojs={champion:{}};LOLherojs.champion.'+heroDataId+'=',''); 166 data = data.substr(0 ,data.length-1); 167 data = reconvert(data); 168 var heroDetailJson = JSON.parse(data); 169 var heroVerDetailPath = heroVerPath + '\\'+heroDataId+'.json'; 170 try{ 171 var w = fs.writeFileSync(heroVerDetailPath, data); 172 }catch(e){ 173 console.log('写入错误',heroVerDetailPath,e); 174 return '写入错误:'+"\n"+heroVerDetailPath+"\n"+e; 175 } 176 console.log('写入成功',heroVerDetailPath); 177 178 // 下载英雄皮肤图片 179 for(var skin in heroDetailJson.data.skins){ 180 skin = heroDetailJson.data.skins[skin]; 181 var skinImgUrl = heroDetailSkinPath + skin.id + '.jpg'; 182 console.log("抓取皮肤图片",skin.id,skinImgUrl); 183 var opt = getRequireOption(skinImgUrl); 184 var res = request(opt.method,opt.path,opt); 185 var data = res.getBody(); 186 var heroVerSkinImgPath = heroVerSkinPath + '\\'+skin.id + '.jpg'; 187 try{ 188 var w = fs.writeFileSync(heroVerSkinImgPath, data); 189 }catch(e){ 190 console.log('写入错误',heroVerSkinImgPath,e); 191 return '写入错误:'+"\n"+heroVerSkinImgPath+"\n"+e; 192 } 193 console.log('写入成功',heroVerSkinImgPath); 194 } 195 // 下载英雄技能图片 主动 196 for(var spell in heroDetailJson.data.spells){ 197 spell = heroDetailJson.data.spells[spell]; 198 var spellImgUrl = heroDetailSkillPath + spell.image.full; 199 console.log("抓取主动技能图片",spell.image.full,spellImgUrl); 200 var opt = getRequireOption(spellImgUrl); 201 var res = request(opt.method,opt.path,opt); 202 var data = res.getBody(); 203 var heroVerSpellImgPath = heroVerSkillPath + '\\'+spell.image.full; 204 try{ 205 var w = fs.writeFileSync(heroVerSpellImgPath, data); 206 }catch(e){ 207 console.log('写入错误',heroVerSpellImgPath,e); 208 return '写入错误:'+"\n"+heroVerSpellImgPath+"\n"+e; 209 } 210 console.log('写入成功',heroVerSpellImgPath); 211 } 212 // 下载英雄技能图片 被动 213 var passiveImgUrl = heroDetailPSkillPath + heroDetailJson.data.passive.image.full; 214 console.log("抓取被动技能图片",heroDetailJson.data.passive.image.full,passiveImgUrl); 215 var opt = getRequireOption(passiveImgUrl); 216 var res = request(opt.method,opt.path,opt); 217 var data = res.getBody(); 218 var heroVerPassiveImgPath = heroVerSkillPath + '\\'+heroDetailJson.data.passive.image.full; 219 try{ 220 var w = fs.writeFileSync(heroVerPassiveImgPath, data); 221 }catch(e){ 222 console.log('写入错误',heroVerPassiveImgPath,e); 223 return '写入错误:'+"\n"+heroVerPassiveImgPath+"\n"+e; 224 } 225 console.log('写入成功',heroVerPassiveImgPath); 226 227 //break; //test 228 } 229 return ''; 230 } 231 232 function reconvert(str){ 233 str = str.replace(/(\\u)(\w{1,4})/gi,function($0){ 234 return (String.fromCharCode(parseInt((escape($0).replace(/(%5Cu)(\w{1,4})/g,"$2")),16))); 235 }); 236 str = str.replace(/(&#x)(\w{1,4});/gi,function($0){ 237 return String.fromCharCode(parseInt(escape($0).replace(/(%26%23x)(\w{1,4})(%3B)/g,"$2"),16)); 238 }); 239 str = str.replace(/(&#)(\d{1,6});/gi,function($0){ 240 return String.fromCharCode(parseInt(escape($0).replace(/(%26%23)(\d{1,6})(%3B)/g,"$2"))); 241 }); 242 return str; 243 } 244 245 function deleteFolderRecursive(path) { 246 var files = []; 247 if( fs.existsSync(path) ) { 248 files = fs.readdirSync(path); 249 files.forEach(function(file,index){ 250 var curPath = path + "/" + file; 251 if(fs.statSync(curPath).isDirectory()) { // recurse 252 deleteFolderRecursive(curPath); 253 } else { // delete file 254 fs.unlinkSync(curPath); 255 } 256 }); 257 fs.rmdirSync(path); 258 } 259 }; 260 261 function getRequireOption(pathStr){ 262 return op={ 263 host:pathStr.match(/http[s]?:\/\/[^\\|\/]*/)[0].replace(/http[s]?:\/\//,''), 264 port:80, 265 method:'GET', 266 path:pathStr, 267 headers:{ 268 'Host':pathStr.match(/http[s]?:\/\/[^\\|\/]*/)[0].replace(/http[s]?:\/\//,''), 269 "User-Agent":"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.92 Safari/537.1 LBBROWSER", 270 "Referer":pathStr.match(/http[s]?:\/\/[^\\|\/]*/)[0].replace(/http[s]?:\/\//,'') 271 } 272 } 273 }
jade模板代码(indexTemplate.jade):
1 doctype html 2 html 3 head 4 title LOL英雄 5 script(src='/javascripts/jquery-3.1.1.min.js') 6 script(src='/javascripts/bootstrap.min.js') 7 script(src='/core-js/client/shim.min.js') 8 script(src='/zone.js/dist/zone.js') 9 script(src='/jade/jade.js') 10 script(src='/systemjs/dist/system.src.js') 11 script(src='/javascripts/systemjs.config.js') 12 script. 13 System.import('app').catch(function(err){ console.error(err); }); 14 link(href='/stylesheets/bootstrap.min.css', rel='stylesheet') 15 style. 16 html,body{background-color: black;color:rgb(255,215,000); overflow: hidden; height:100%;} 17 .main,.selHeroMain{ 18 width:100%;height:100%; 19 } 20 .selHeroContain{ 21 border-radius: 50%; 22 border:3px rgb(255,215,000) solid; 23 width:60%; 24 height:90%; 25 margin: 0 auto; 26 } 27 .selHeroDivOut{ 28 border:1px black solid; 29 width:50%; 30 height:300%; 31 margin: auto; 32 margin-top: -50%; 33 background-color: black; 34 } 35 .selHeroDiv{ 36 position:absolute; 37 display: none; 38 border-radius: 50%; 39 border:2px rgb(255,215,000) solid; 40 background-size:196% 100%; 41 background-repeat:no-repeat; 42 background-position:100% 100%; 43 overflow: hidden; 44 box-shadow: 0px 0px 30px rgb(255,215,000); 45 } 46 .selHeroDiv img{ 47 height:100%; 48 border-radius: 50%; 49 } 50 .leftHeros,.rightHeros{ 51 width:15%; 52 height:90%; 53 position:absolute; 54 top:0px; 55 overflow: hidden; 56 } 57 .leftHeros{ 58 left:0px; 59 } 60 .rightHeros{ 61 right:0px; 62 } 63 .leftHeros ul,.rightHeros ul{ 64 height:90%; 65 margin-top: 30%; 66 padding-left: 0px; 67 } 68 .leftHeros li,.rightHeros li{ 69 white-space:nowrap; 70 font-size:20px; 71 list-style-type:none; 72 height:18%; 73 padding:1% 0; 74 border-bottom: 1px rgb(255,215,000) solid; 75 overflow: hidden; 76 } 77 .leftHeros li{ 78 text-align: left; 79 } 80 .rightHeros li{ 81 text-align: right; 82 } 83 .leftHeros img,.rightHeros img{ 84 vertical-align: bottom; 85 height:100%; 86 overflow: hidden; 87 } 88 .leftHeros span,.rightHeros span{ 89 overflow: hidden; 90 } 91 /* css3实现图片划过一束光闪过效果 */ 92 .selHeroDiv:before { 93 content: ""; position: absolute; width:200px; height: 100%; top: 0; left: -350px; overflow: hidden; 94 background: -moz-linear-gradient(left, rgba(255,255,255,0)0, rgba(255,255,255,.2)50%, rgba(255,255,255,0)100%); 95 background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(50%, rgba(255,255,255,.2)), color-stop(100%, rgba(255,255,255,0))); 96 background: -webkit-linear-gradient(left, rgba(255,255,255,0)0, rgba(255,255,255,.2)50%, rgba(255,255,255,0)100%); 97 background: -o-linear-gradient(left, rgba(255,255,255,0)0, rgba(255,255,255,.2)50%, rgba(255,255,255,0)100%); 98 -webkit-transform: skewX(-25deg); 99 -moz-transform: skewX(-25deg); 100 animation:selHeroDivAnimate 9s infinite linear; 101 } 102 .selHeroDiv:hover:before { left: 150%; animation:selHeroDivAnimateHover 1s 1 ease 0s; /*transition: left 1s ease 0s;*/} 103 @keyframes selHeroDivAnimate 104 { 105 0% {left: -350px;} 106 90% {left: -350px;} 107 100% {left: 150%;} 108 } 109 @keyframes selHeroDivAnimateHover 110 { 111 0% {left: -350px;} 112 100% {left: 150%;} 113 } 114 .pullDown{ 115 width:100%; 116 height:10%; 117 position:absolute; 118 top:0px; 119 text-align: center; 120 vertical-align: middle; 121 font-size: 50px; 122 color:white; 123 cursor:pointer; 124 } 125 .pullDown span{width:100%;position: absolute;top: 0px;left:0px;animation:pullDown 2s infinite linear;} 126 @keyframes pullDown 127 { 128 0% {top: 0px;} 129 50% {top: 20px;} 130 100% {top: 0px;} 131 } 132 .heroList{ 133 width:100%; 134 height:60%; 135 position:absolute; 136 opacity:0.2; 137 background: gray; 138 top:90%; 139 } 140 /*.heroList:hover{ 141 opacity:1; 142 background: black; 143 top:40%; 144 transition: opacity,top 1s ease 0s; 145 }*/ 146 .pullUp{ 147 position:relative; 148 top:0px; 149 color:white; 150 text-align: right; 151 display: none; 152 cursor:pointer; 153 } 154 .hListMain{display: none; height: 95%;} 155 .hListSearchBar{height: 10%;} 156 .hListStyle1,.hListStyle2{vertical-align: middle; font-size: 30px; height:85%; overflow-y: auto; overflow-x: hidden;} 157 .hListStyle1 .row,.hListStyle2 .row{ margin-top: 15px; border-bottom: 1px rgb(255,215,000) solid; } 158 .hListStyle1 .row{cursor: pointer;} 159 .hListStyle2 .row{border: none;} 160 .hListStyle1 .row div{ height: 100px; line-height: 100px;} 161 .hListStyle2 .row {width:70%; margin:0 auto;} 162 .hListStyle2 .row div{cursor: pointer;} 163 .hListStyle2{display: none;} 164 .hero{position: absolute;width:80%; border: 1px rgb(255,215,000) solid;top:-100%; 165 border-radius: 30px; top:10%;left:10%;background: #2B2B2B; font-size: 30px; height: 80%; /*display: none;*/} 166 .heroTitle{height:20%;width:100%;} 167 .heroData{overflow-y: auto; overflow-x: hidden;height:75%;width:100%;font-size: 15px;} 168 .heroData .row{margin-bottom: 5px; } 169 .heroClose{color:white; font-size: 10px; cursor: pointer;} 170 .getHeroList{position: absolute;top:0px; right: 0px; color: black;font-style: 13px;cursor: pointer;z-index:99;} 171 .leftHeros li:first-child img{border:1px rgb(255,215,000) solid} 172 .loadingDiv{width:100%;height:100%;top:0px;left:0px;background:gray;font-size:40px;position:absolute;text-align:center;padding:20% 0;opacity:0.75;text-shadow: 0px 0px 40px rgb(255,000,000);} 173 body 174 script. 175 window.onresize = function(){ 176 var selHeroDivHW = $(".selHeroDivOut").width(); 177 $(".selHeroDiv").width(selHeroDivHW); 178 $(".selHeroDiv").height(selHeroDivHW); 179 $(".selHeroDiv").offset({"left":$(".selHeroContain").offset().left+($(".selHeroContain").width()-selHeroDivHW)*0.5 180 ,"top":$(".selHeroContain").offset().top+($(".selHeroContain").height()-selHeroDivHW)*0.5}); 181 $(".selHeroDiv").show(); 182 }; 183 function stopPropagation(e){ 184 window.event? window.event.cancelBubble = true : e.stopPropagation(); 185 } 186 Array.prototype.contains=function(obj) { 187 var index=this.length; 188 while (index--){ 189 if(this[index]===obj){ 190 return true; 191 } 192 } 193 return false; 194 } 195 .main
Angularjs2 模板代码(selectHero.html)【理论上应该分组件,通过组件父子间通信来完成】:
1 <div class='selHeroMain' (mousewheel)="showHideHeroListPanel()" > 2 <div class='selHeroContain' #selHeroContain> 3 <div class='selHeroDivOut' #selHeroDivOut> 4 <div class='selHeroDiv' [ngStyle]="{'background-image': styleExp}" #selHeroDiv> 5 </div> 6 </div> 7 </div> 8 <div class='leftHeros'> 9 <ul> 10 <li>玩家1:<span><img src='{{leftPlayImg1}}' width='133' height='120' /></span></li> 11 <li>玩家2:<span><img src='{{leftPlayImg2}}' width='133' height='120' /></span></li> 12 <li>玩家3:<span><img src='{{leftPlayImg3}}' width='133' height='120' /></span></li> 13 <li>玩家4:<span><img src='{{leftPlayImg4}}' width='133' height='120' /></span></li> 14 <li>玩家5:<span><img src='{{leftPlayImg5}}' width='133' height='120' /></span></li> 15 </ul> 16 </div> 17 <div class='rightHeros'> 18 <ul> 19 <li><span><img src='{{rightPlayImg1}}' width='133' height='120' />:玩家1</span></li> 20 <li><span><img src='{{rightPlayImg2}}' width='133' height='120' />:玩家2</span></li> 21 <li><span><img src='{{rightPlayImg3}}' width='133' height='120' />:玩家3</span></li> 22 <li><span><img src='{{rightPlayImg4}}' width='133' height='120' />:玩家4</span></li> 23 <li><span><img src='{{rightPlayImg5}}' width='133' height='120' />:玩家5</span></li> 24 </ul> 25 </div> 26 <!--<div class='pullDown'><span>下拉/点击 选择英雄</span></div>--> 27 </div> 28 <div class='heroList container' [@openClosePanel]="statePanelExpression" #heroList > 29 <div class='pullDown' (click)="showHeroListPanel()" #pullDown ><span>下拉/点击 选择英雄</span></div> 30 <div class='pullUp' (click)="hideHeroListPanel()" #pullUp >关闭</div> 31 <div class='hListMain' #hListMain > 32 <div class='hListSearchBar form-inline text-center'> 33 <div class="row"> 34 <div class="col-lg-1 col-md-1 col-sm-1"> 35 <div class="dropdown"> 36 <button type="button" class="btn dropdown-toggle btn-primary" id="dropdownMenuVer" data-toggle="dropdown">版本 37 <span class="caret"></span> 38 </button> 39 <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenuVer"> 40 <li role="presentation" *ngFor="let ver of heroVers.vers; let i = index" [ngClass]="{'active':ver==curVer}" (click)="getNewVersion(ver)"> 41 <a role="menuitem" tabindex="-1" href="#" >{{ver}}</a> 42 </li> 43 </ul> 44 </div> 45 </div> 46 <div class="col-lg-1 col-md-1 col-sm-1"> 47 <div class="dropdown"> 48 <button type="button" class="btn dropdown-toggle btn-primary" id="dropdownMenuVer" data-toggle="dropdown">英雄类型 49 <span class="caret"></span> 50 </button> 51 <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenuVer"> 52 <li role="presentation" *ngFor="let htc of heroTypeCList; let i = index" [ngClass]="{'active':htc==heroTypeCCur}" (click)="filterType(heroTypeCList[i])"> 53 <a role="menuitem" tabindex="-1" href="#">{{heroTypeCList[i]}}</a> 54 </li> 55 </ul> 56 </div> 57 </div> 58 <div class="col-lg-1 col-md-1 col-sm-1"><input type="text" class="form-control" id="name" placeholder="输入英雄名称" #heroFilterName (keyup)="searchHeroByName(heroFilterName.value)"></div> 59 <div class="col-lg-8 col-md-8 col-sm-8">检索条件: {{heroTypeCCur}}英雄 | 名称:{{heroFilterName.value}}</div> 60 <div class="col-lg-1 col-md-1 col-sm-1"> 61 <div class="dropdown pull-right"> 62 <button type="button" class="btn dropdown-toggle btn-primary" id="dropdownMenuVer" data-toggle="dropdown">显示方式 63 <span class="caret"></span> 64 </button> 65 <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenuVer"> 66 <li role="presentation" [ngClass]="{'active':showListTypeCur=='LB'}"> 67 <a role="menuitem" tabindex="-1" href="#" #menuitemLB (click)="heroListLB()" >列表</a> 68 </li> 69 <li role="presentation" [ngClass]="{'active':showListTypeCur=='TZ'}"> 70 <a role="menuitem" tabindex="-1" href="#" #menuitemTZ (click)="heroListTZ()" >图阵</a> 71 </li> 72 </ul> 73 </div> 74 </div> 75 </div> 76 </div> 77 <div class='hListStyle1' #hListStyle1 > 78 <div class="row text-center" (click)="showHeroDetail(heroData)" (mouseenter)="showBigPic(heroData)" *ngFor="let heroData of heroDataList; let i = index"> 79 <div class="col-lg-1 col-md-1 col-sm-1"> 80 </div> 81 <div class="col-lg-2 col-md-2 col-sm-2"> 82 <img src='/{{curVer}}/imgs/{{heroData.image.full}}' width="90" /> 83 </div> 84 <div class="col-lg-1 col-md-1 col-sm-1"> 85 {{heroData.id}} 86 </div> 87 <div class="col-lg-2 col-md-2 col-sm-2"> 88 {{heroData.name}} 89 </div> 90 <div class="col-lg-2 col-md-2 col-sm-2"> 91 {{heroData.title}} 92 </div> 93 <div class="col-lg-2 col-md-2 col-sm-2"> 94 {{heroData.tags}} 95 </div> 96 <div class="col-lg-2 col-md-2 col-sm-2"> 97 </div> 98 </div> 99 </div> 100 <div class='hListStyle2' #hListStyle2 > 101 <div class="row text-center"> 102 <div class="col-lg-2 col-md-2 col-sm-2" (click)="showHeroDetail(heroData)" (mouseenter)="showBigPic(heroData)" *ngFor="let heroData of heroDataList; let i = index"> 103 <a data-toggle="tooltip" data-placement="top" title="{{heroData.id}}:{{heroData.name}}:{{heroData.title}}:{{heroData.tags}}"> 104 <img src='/{{curVer}}/imgs/{{heroData.image.full}}' width="120" /> 105 </a> 106 </div> 107 </div> 108 </div> 109 </div> 110 </div> 111 <div *ngIf="heroShowDetailAllytips && heroShowDetailAllytips.length>0" class='hero container' [@openCloseHero]="stateHeroExpression" #hero > 112 <p class="heroClose text-right" (click)="hideHeroDetail()" >关闭</p> 113 <div class="heroTitle"> 114 <div class="row"> 115 <div class="col-lg-2 col-md-2 col-sm-2"> 116 <img src='/{{curVer}}/imgs/{{heroShowDetail.id}}.png' width="120" /> 117 </div> 118 <div class="col-lg-6 col-md-6 col-sm-6"> 119 ({{heroShowDetail.id}}) {{heroShowDetail.name}} : {{heroShowDetail.title}} 120 </div> 121 <div class="col-lg-2 col-md-2 col-sm-2 text-right"> 122 <span class="badge">[{{heroShowDetail.tags}}]</span> 123 </div> 124 </div> 125 </div> 126 <div class="heroData"> 127 <div class="row"> 128 <div class="col-lg-2 col-md-2 col-sm-2"></div> 129 <div class="col-lg-8 col-md-8 col-sm-8"> 130 <div id="myCarousel" class="carousel slide" #myCarousel> 131 <!-- 轮播(Carousel)指标 --> 132 <ol class="carousel-indicators"> 133 <li data-target="#myCarousel" [ngClass]="{'active':i==0}" *ngFor="let skin of heroShowDetailSkins; let i = index" ></li> 134 </ol> 135 <!-- 轮播(Carousel)项目 --> 136 <div class="carousel-inner"> 137 <div class="item" [ngClass]="{'active':i==0}" *ngFor="let skin of heroShowDetailSkins; let i = index" > 138 <img src="/{{curVer}}/skin/{{skin.id}}.jpg" alt="{{skin.name}}"> 139 <div class="carousel-caption">{{skin.name}}</div> 140 </div> 141 </div> 142 <!-- 轮播(Carousel)导航 --> 143 <a class="carousel-control left" href="#myCarousel" 144 data-slide="prev">‹ 145 </a> 146 <a class="carousel-control right" href="#myCarousel" 147 data-slide="next">› 148 </a> 149 </div> 150 </div> 151 <div class="col-lg-2 col-md-2 col-sm-2"></div> 152 </div> 153 <div class="row"> 154 <div class="col-lg-1 col-md-1 col-sm-1"></div> 155 <div class="col-lg-1 col-md-1 col-sm-1">故事 156 </div> 157 <div class="col-lg-10 col-md-10 col-sm-10"> 158 </div> 159 </div> 160 <div class="row"> 161 <div class="col-lg-2 col-md-2 col-sm-2"></div> 162 <div class="col-lg-8 col-md-8 col-sm-8">{{heroShowDetail.lore}} 163 </div> 164 <div class="col-lg-2 col-md-2 col-sm-2"></div> 165 </div> 166 <div class="row"> 167 <div class="col-lg-1 col-md-1 col-sm-1"></div> 168 <div class="col-lg-1 col-md-1 col-sm-1">技能 169 </div> 170 <div class="col-lg-10 col-md-10 col-sm-10"> 171 </div> 172 </div> 173 <div class="row"> 174 <div class="col-lg-2 col-md-2 col-sm-2"></div> 175 <div class="col-lg-1 col-md-1 col-sm-1"><img src='/{{curVer}}/skill/{{heroShowDetailPassiveImg.full}}' width="80" /></div> 176 <div class="col-lg-7 col-md-7 col-sm-7"> 177 {{heroShowDetailPassive.name}}<br/>{{heroShowDetailPassive.description}} 178 </div> 179 <div class="col-lg-2 col-md-2 col-sm-2"></div> 180 </div> 181 <div class="row"> 182 <div class="col-lg-2 col-md-2 col-sm-2"></div> 183 <div class="col-lg-1 col-md-1 col-sm-1"><img src='/{{curVer}}/skill/{{heroShowDetailSpells1.image}}' width="80" /></div> 184 <div class="col-lg-3 col-md-3 col-sm-3"> 185 {{heroShowDetailSpells1.id}}<br/> 186 {{heroShowDetailSpells1.name}}<br/> 187 {{heroShowDetailSpells1.description}}<br/> 188 {{removeTag(heroShowDetailSpells1.tooltip)}} 189 </div> 190 <div class="col-lg-1 col-md-1 col-sm-1"><img src='/{{curVer}}/skill/{{heroShowDetailSpells2.image}}' width="80" /></div> 191 <div class="col-lg-3 col-md-3 col-sm-3"> 192 {{heroShowDetailSpells2.id}}<br/> 193 {{heroShowDetailSpells2.name}}<br/> 194 {{heroShowDetailSpells2.description}}<br/> 195 {{removeTag(heroShowDetailSpells2.tooltip)}} 196 </div> 197 <div class="col-lg-2 col-md-2 col-sm-2"></div> 198 </div> 199 <div class="row"> 200 <div class="col-lg-2 col-md-2 col-sm-2"></div> 201 <div class="col-lg-1 col-md-1 col-sm-1"><img src='/{{curVer}}/skill/{{heroShowDetailSpells3.image}}' width="80" /></div> 202 <div class="col-lg-3 col-md-3 col-sm-3"> 203 {{heroShowDetailSpells3.id}}<br/> 204 {{heroShowDetailSpells3.name}}<br/> 205 {{heroShowDetailSpells3.description}}<br/> 206 {{removeTag(heroShowDetailSpells3.tooltip)}} 207 </div> 208 <div class="col-lg-1 col-md-1 col-sm-1"><img src='/{{curVer}}/skill/{{heroShowDetailSpells4.image}}' width="80" /></div> 209 <div class="col-lg-3 col-md-3 col-sm-3"> 210 {{heroShowDetailSpells4.id}}<br/> 211 {{heroShowDetailSpells4.name}}<br/> 212 {{heroShowDetailSpells4.description}}<br/> 213 {{removeTag(heroShowDetailSpells4.tooltip)}} 214 </div> 215 <div class="col-lg-2 col-md-2 col-sm-2"></div> 216 </div> 217 <div class="row"> 218 <div class="col-lg-1 col-md-1 col-sm-1"></div> 219 <div class="col-lg-1 col-md-1 col-sm-1">技巧 220 </div> 221 <div class="col-lg-10 col-md-10 col-sm-10"> 222 </div> 223 </div> 224 <div class="row"> 225 <div class="col-lg-2 col-md-2 col-sm-2"></div> 226 <div class="col-lg-1 col-md-1 col-sm-1">己方技巧:</div> 227 <div class="col-lg-7 col-md-7 col-sm-7"> 228 <div class="row" *ngFor="let str of heroShowDetailAllytips; let i = index">{{str}}</div> 229 </div> 230 <div class="col-lg-2 col-md-2 col-sm-2"></div> 231 </div> 232 <div class="row"> 233 <div class="col-lg-2 col-md-2 col-sm-2"></div> 234 <div class="col-lg-1 col-md-1 col-sm-1">敌方技巧:</div> 235 <div class="col-lg-7 col-md-7 col-sm-7"> 236 <div class="row" *ngFor="let str of heroShowDetailEnemytips; let i = index">{{str}}</div> 237 </div> 238 <div class="col-lg-2 col-md-2 col-sm-2"></div> 239 </div> 240 </div> 241 242 </div> 243 <div class="getHeroList" #getHeroList (click)="doGetHeroList()" [style.color]="loadFinished?'black':'gold'">点此抓取LOL英雄列表 ^-^</div> 244 <div class='loadingDiv' [style.display]="loadFinished?'none':'block'">{{loadingText}}</div>
Angularjs2 ts代码(app.component.ts):
1 import {Component, OnInit, ViewChild, Renderer, ElementRef, AfterViewInit, animate, trigger,state,style,transition} from '@angular/core'; 2 import {Http,Response} from '@angular/http'; 3 import 'rxjs/add/operator/toPromise'; 4 import 'rxjs/add/operator/catch'; 5 import 'rxjs/add/operator/debounceTime'; 6 import 'rxjs/add/operator/distinctUntilChanged'; 7 import 'rxjs/add/operator/map'; 8 import 'rxjs/add/operator/switchMap'; 9 10 @Component({ 11 selector: '.main', 12 animations: [ 13 trigger( 14 'openClosePanel', 15 [ 16 state('close, void', style({opacity:'0.2',top:'90%'})), 17 state('open', style({opacity:'1',top:'40%'})), 18 transition( 19 'close <=> open', [animate(500)]) 20 ]), 21 trigger( 22 'openCloseHero', 23 [ 24 state('close, void', style({opacity:'0',top:'-100%'})), 25 state('open', style({opacity:'1',top:'10%'})), 26 transition( 27 'close <=> open', [animate(500)]), 28 transition( 29 'void => open', [animate(500)]) 30 ]) 31 ], 32 templateUrl: '/selectHero.html' 33 }) 34 export class AppComponent implements AfterViewInit,OnInit { 35 styleExp = 'url("/images/main.jpg")'; 36 leftPlayImg1 = '/images/angularjs.png'; 37 leftPlayImg2 = '/images/expressjs.jpg'; 38 leftPlayImg3 = '/images/bootstrap.jpg'; 39 leftPlayImg4 = '/images/nodejs.png'; 40 leftPlayImg5 = '/images/npm.jpg'; 41 rightPlayImg1 = '/images/spring.jpg'; 42 rightPlayImg2 = '/images/struts2.jpg'; 43 rightPlayImg3 = '/images/typescript.jpg'; 44 rightPlayImg4 = '/images/tomcat.jpg'; 45 rightPlayImg5 = '/images/java.png'; 46 heroTypeCList = ["所有","战士","坦克","刺客","法师","射手","辅助"]; 47 heroTypeCCur = "所有"; 48 showListTypeCur = "LB"; 49 // loading 50 loadFinished = false; 51 loadingText = 'Hellow World! 你好!'; 52 53 // 获取dom元素 start 54 // 英雄大头像圈 55 @ViewChild('selHeroDiv') selHeroDiv: ElementRef; 56 @ViewChild('selHeroDivOut') selHeroDivOut: ElementRef; 57 @ViewChild('selHeroContain') selHeroContain: ElementRef; 58 // 英雄列表面板 59 @ViewChild('heroList') heroList: ElementRef; 60 @ViewChild('hListMain') hListMain: ElementRef; 61 @ViewChild('pullDown') pullDown: ElementRef; 62 @ViewChild('pullUp') pullUp: ElementRef; 63 // 英雄列表 图阵 切换 64 @ViewChild('hListStyle1') hListStyle1: ElementRef; 65 @ViewChild('hListStyle2') hListStyle2: ElementRef; 66 // 抓取LOL服务器数据 67 @ViewChild('getHeroList') getHeroListDom: ElementRef; 68 // 显示英雄详细信息 69 @ViewChild('hero') hero: ElementRef; 70 // 英雄过滤名称 71 @ViewChild('heroFilterName') heroFilterName: ElementRef; 72 73 74 // 获取dom元素 end 75 76 constructor(private renderer: Renderer,private http: Http) { 77 // 初始:英雄列表隐藏 78 this.statePanelExpression = 'close'; 79 // 初始:英雄详细隐藏 80 this.stateHeroExpression = 'close'; 81 } 82 83 ngAfterViewInit() { 84 // 初期设置大头像位置 start 85 var selHeroDivHW = this.selHeroDivOut.nativeElement.clientWidth; 86 var selHeroContainHeight = this.selHeroContain.nativeElement.clientHeight; 87 var selHeroContainWidth = this.selHeroContain.nativeElement.clientWidth; 88 var selHeroContainLeft = this.selHeroContain.nativeElement.offsetLeft; 89 var selHeroContainTop = this.selHeroContain.nativeElement.offsetTop; 90 91 this.renderer.setElementStyle(this.selHeroDiv.nativeElement, 'width', selHeroDivHW+'px'); 92 this.renderer.setElementStyle(this.selHeroDiv.nativeElement, 'height', selHeroDivHW+'px'); 93 this.renderer.setElementStyle(this.selHeroDiv.nativeElement, 'left', selHeroContainLeft+(selHeroContainWidth-selHeroDivHW)*0.5 +'px'); 94 this.renderer.setElementStyle(this.selHeroDiv.nativeElement, 'top', selHeroContainTop+(selHeroContainHeight-selHeroDivHW)*0.5 +'px'); 95 96 this.renderer.setElementStyle(this.selHeroDiv.nativeElement, 'display', 'block'); 97 // 初期设置大头像位置 end 98 } 99 100 // 英雄列表面板显示隐藏控制 start 101 statePanelExpression: string; 102 showHeroListPanel() { 103 this.renderer.setElementStyle(this.pullDown.nativeElement, 'display', 'none'); 104 this.statePanelExpression = 'open'; 105 this.renderer.setElementStyle(this.pullUp.nativeElement, 'display', 'block'); 106 this.renderer.setElementStyle(this.heroList.nativeElement, 'background', 'black'); 107 this.renderer.setElementStyle(this.hListMain.nativeElement, 'display', 'block'); 108 } 109 hideHeroListPanel() { 110 this.renderer.setElementStyle(this.pullUp.nativeElement, 'display', 'none'); 111 this.statePanelExpression = 'close'; 112 this.renderer.setElementStyle(this.pullDown.nativeElement, 'display', 'block'); 113 this.renderer.setElementStyle(this.heroList.nativeElement, 'background', 'gray'); 114 this.renderer.setElementStyle(this.hListMain.nativeElement, 'display', 'none'); 115 } 116 showHideHeroListPanel(){ 117 if(this.statePanelExpression == 'close'){ 118 this.showHeroListPanel(); 119 }else{ 120 this.hideHeroListPanel(); 121 } 122 } 123 // 英雄列表面板显示隐藏控制 end 124 125 // 英雄列表 图阵 切换 start 126 heroListLB(){ 127 this.renderer.setElementStyle(this.hListStyle2.nativeElement, 'display', 'none'); 128 this.renderer.setElementStyle(this.hListStyle1.nativeElement, 'display', 'block'); 129 this.showListTypeCur = "LB"; 130 } 131 heroListTZ(){ 132 this.renderer.setElementStyle(this.hListStyle1.nativeElement, 'display', 'none'); 133 this.renderer.setElementStyle(this.hListStyle2.nativeElement, 'display', 'block'); 134 this.showListTypeCur = "TZ"; 135 } 136 // 英雄列表 图阵 切换 end 137 138 // 抓取LOL服务器数据 139 doGetHeroList(){ 140 this.renderer.setElementStyle(this.getHeroListDom.nativeElement, 'display', 'none'); 141 this.http.get('/getHeroList').toPromise(). 142 then(res => 143 { 144 alert(res.text()); 145 this.renderer.setElementStyle(this.getHeroListDom.nativeElement, 'display', 'block'); 146 this.ngAfterViewInit(); 147 this.ngOnInit(); 148 }).catch((e)=>console.log(e)); 149 } 150 151 // 显示英雄详细信息 start 152 stateHeroExpression: string; 153 curHeroDataId = ''; 154 heroShowDetail:any = {}; 155 heroShowDetailPassive:any = {}; 156 heroShowDetailPassiveImg = ''; 157 heroShowDetailSkins : Array<any> = []; 158 heroShowDetailSpells1 :any = {}; 159 heroShowDetailSpells2 :any = {}; 160 heroShowDetailSpells3 :any = {}; 161 heroShowDetailSpells4 :any = {}; 162 heroShowDetailAllytips : Array<any> = []; 163 heroShowDetailEnemytips : Array<any> = []; 164 showHeroDetail(heroData:any){ 165 // 获取英雄详细数据 166 this.curHeroDataId = heroData.id; 167 this.http.get('/' + this.curVer + '/'+ heroData.id +'.json').toPromise() 168 .then((res:Response)=>{ 169 if(JSON.parse(res.text()).data.id == this.curHeroDataId){ 170 this.heroShowDetail = JSON.parse(res.text()).data; 171 this.heroShowDetailSkins = JSON.parse(res.text()).data.skins; 172 this.heroShowDetail.tags = this.heroTypeEC2C(this.heroShowDetail.tags); 173 this.heroShowDetailPassive = JSON.parse(res.text()).data.passive; 174 this.heroShowDetailPassiveImg = JSON.parse(res.text()).data.passive.image; 175 176 this.heroShowDetailSpells1 = JSON.parse(res.text()).data.spells[0]; 177 this.heroShowDetailSpells2 = JSON.parse(res.text()).data.spells[1]; 178 this.heroShowDetailSpells3 = JSON.parse(res.text()).data.spells[2]; 179 this.heroShowDetailSpells4 = JSON.parse(res.text()).data.spells[3]; 180 this.heroShowDetailSpells1.image = JSON.parse(res.text()).data.spells[0].image.full; 181 this.heroShowDetailSpells2.image = JSON.parse(res.text()).data.spells[1].image.full; 182 this.heroShowDetailSpells3.image = JSON.parse(res.text()).data.spells[2].image.full; 183 this.heroShowDetailSpells4.image = JSON.parse(res.text()).data.spells[3].image.full; 184 this.heroShowDetailAllytips = JSON.parse(res.text()).data.allytips; 185 this.heroShowDetailEnemytips = JSON.parse(res.text()).data.enemytips; 186 } 187 }).catch(this.handleError); 188 this.stateHeroExpression = 'open'; 189 } 190 hideHeroDetail() { 191 this.stateHeroExpression = 'close'; 192 } 193 // 显示英雄详细信息 end 194 195 // 英雄列表所有版本号 196 heroVers = JSON.parse('{}'); 197 heroDataList : Array<any> = []; 198 bakHeroDataList : Array<any> = []; 199 curVer = ''; 200 ngOnInit(){ 201 // 取得英雄列表所有版本号 202 // console.log('client get hero version'); 203 this.loadingText = '开始取得英雄列表所有版本号'; 204 this.http.get('/getHeroVers').toPromise() 205 .then((res:Response)=>{ 206 this.heroVers = this.extractVersData(res); 207 if(!this.heroVers && !this.heroVers.vers){ 208 this.loadingText = '服务器尚未抓取英雄列表,请点击右上角文字抓取数据。'; 209 return; 210 } 211 this.curVer = (this.heroVers && this.heroVers.vers &&this.heroVers.vers.length>0)?this.heroVers.vers[0]:''; 212 if(this.curVer!=''){ 213 // 获取英雄列表json 214 this.loadingText = '开始取得英雄列表'; 215 this.http.get('/' + this.curVer + '/herolist.json').toPromise() 216 .then((res:Response)=>{ 217 if(JSON.parse(res.text()).version == this.curVer){ 218 this.heroDataList = []; 219 for (var key in JSON.parse(res.text()).keys) { 220 var heroIdTmp = JSON.parse(res.text()).keys[key]; 221 this.heroDataList.push( 222 JSON.parse(res.text()).data[heroIdTmp] 223 ); 224 this.bakHeroDataList.push( 225 JSON.parse(res.text()).data[heroIdTmp] 226 ); 227 } 228 for (var i = this.heroDataList.length - 1; i >= 0; i--) { 229 this.heroDataList[i].tags = this.heroTypeEC2C(this.heroDataList[i].tags); 230 this.bakHeroDataList[i].tags = this.heroTypeEC2C(this.bakHeroDataList[i].tags); 231 } 232 this.heroDataTypeList = this.heroDataList; 233 this.loadingText = '随机生成对战英雄'; 234 this.genFight(); 235 this.loadingText = '加载完成'; 236 this.loadFinished = true; 237 } 238 }).catch(this.handleError); 239 }else{ 240 this.loadingText = '服务器尚未抓取英雄列表,请点击右上角文字抓取数据。'; 241 } 242 }).catch(this.handleError); 243 } 244 245 genFight(){ 246 // 随机生成对战英雄 247 var max = this.heroDataList.length; 248 var randomI = Math.floor(Math.random()*max); 249 this.leftPlayImg1 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png'; 250 var myHero = this.heroDataList[randomI]; 251 randomI = Math.floor(Math.random()*max); 252 this.leftPlayImg2 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png'; 253 randomI = Math.floor(Math.random()*max); 254 this.leftPlayImg3 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png'; 255 randomI = Math.floor(Math.random()*max); 256 this.leftPlayImg4 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png'; 257 randomI = Math.floor(Math.random()*max); 258 this.leftPlayImg5 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png'; 259 randomI = Math.floor(Math.random()*max); 260 this.rightPlayImg1 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png'; 261 randomI = Math.floor(Math.random()*max); 262 this.rightPlayImg2 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png'; 263 randomI = Math.floor(Math.random()*max); 264 this.rightPlayImg3 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png'; 265 randomI = Math.floor(Math.random()*max); 266 this.rightPlayImg4 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png'; 267 randomI = Math.floor(Math.random()*max); 268 this.rightPlayImg5 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png'; 269 this.curHeroBigDataId = myHero.id; 270 this.http.get('/' + this.curVer + '/'+ myHero.id +'.json').toPromise() 271 .then((res:Response)=>{ 272 if(JSON.parse(res.text()).data.id == this.curHeroBigDataId){ 273 var max = JSON.parse(res.text()).data.skins.length; 274 var randomI = Math.floor(Math.random()*max); 275 this.styleExp = 'url("/'+this.curVer+'/skin/' 276 +JSON.parse(res.text()).data.skins[randomI].id 277 +'.jpg")'; 278 } 279 }).catch(this.handleError); 280 } 281 282 // 处理英雄列表所有版本号 283 private extractVersData(res: Response) { 284 let body = JSON.parse(res.text()); 285 if(body && body.vers){ 286 body.vers.sort((a : any,b : any)=>b>a); // 简单排序,需要加工 287 } 288 return body || { }; 289 } 290 private handleError (error: Response | any) { 291 console.error(error); 292 return { }; 293 } 294 295 private heroTypeEC2C(ht:Array<string>): Array<string>{ 296 let result : Array<string> = []; 297 for (var i = ht.length - 1; i >= 0; i--) { 298 result.push(ht[i].replace('Mage','法师') 299 .replace('Fighter','战士') 300 .replace('Tank','坦克') 301 .replace('Assassin','刺客') 302 .replace('Marksman','射手') 303 .replace('Support','辅助')); 304 } 305 return result; 306 } 307 removeTag(str:string):string{ 308 if(str) 309 return str.replace(/<.*?>/ig,""); 310 return ''; 311 } 312 313 curHeroBigDataId = ''; 314 showBigPic(heroData:any){ 315 // 修改大图像 316 this.leftPlayImg1 = '/'+this.curVer+'/imgs/'+heroData.id+'.png'; 317 this.curHeroBigDataId = heroData.id; 318 this.http.get('/' + this.curVer + '/'+ heroData.id +'.json').toPromise() 319 .then((res:Response)=>{ 320 if(JSON.parse(res.text()).data.id == this.curHeroBigDataId){ 321 var max = JSON.parse(res.text()).data.skins.length; 322 var randomI = Math.floor(Math.random()*max); 323 this.styleExp = 'url("/'+this.curVer+'/skin/' 324 +JSON.parse(res.text()).data.skins[randomI].id 325 +'.jpg")'; 326 } 327 }).catch(this.handleError); 328 } 329 heroDataTypeList : Array<any> = []; 330 filterType(type:string):void{ 331 // 选择英雄类型 332 this.heroTypeCCur = type; 333 this.heroDataList = this.bakHeroDataList.filter( 334 (hero:any)=>this.heroTypeCCur =='所有' || hero.tags.contains(this.heroTypeCCur)); 335 this.heroDataTypeList = this.heroDataList; 336 } 337 filterTypeFun(hero:any){ 338 return hero.tags.contains(this.heroTypeCCur); 339 } 340 searchHeroByName(value: string){ 341 // 过滤英雄名称 342 this.heroDataList = this.heroDataTypeList.filter( 343 (hero:any)=>value =='' 344 || hero.id.toLowerCase().indexOf(value.toLowerCase())>=0 345 || hero.name.toLowerCase().indexOf(value.toLowerCase())>=0 346 || hero.title.toLowerCase().indexOf(value.toLowerCase())>=0); 347 } 348 tempVer = ''; 349 getNewVersion(ver: string){ 350 // 重新获取英雄版本 351 this.tempVer = ver; 352 if(this.tempVer!='') 353 // 获取英雄列表json 354 this.http.get('/' + this.tempVer + '/herolist.json').toPromise() 355 .then((res:Response)=>{ 356 if(JSON.parse(res.text()).version == this.tempVer){ 357 this.heroDataList = []; 358 for (var key in JSON.parse(res.text()).keys) { 359 var heroIdTmp = JSON.parse(res.text()).keys[key]; 360 this.heroDataList.push( 361 JSON.parse(res.text()).data[heroIdTmp] 362 ); 363 this.bakHeroDataList.push( 364 JSON.parse(res.text()).data[heroIdTmp] 365 ); 366 } 367 for (var i = this.heroDataList.length - 1; i >= 0; i--) { 368 this.heroDataList[i].tags = this.heroTypeEC2C(this.heroDataList[i].tags); 369 this.bakHeroDataList[i].tags = this.heroTypeEC2C(this.bakHeroDataList[i].tags); 370 } 371 this.heroDataTypeList = this.heroDataList; 372 this.genFight(); 373 this.curVer = ver; 374 this.heroTypeCCur = '所有'; 375 this.heroFilterName.nativeElement.value = ''; 376 } 377 }).catch((error: Response | any)=>{ 378 alert('错误:找不到改版本信息'); 379 return {}; 380 }); 381 } 382 383 }
-----
中间效果图如下:
html模板制作:
抓取数据:
数据:
用angularjs2 绑定数据后:
首页:
列表:
详细:
检索:
没数据时:
转载请标明出处:cnblogs.com/wangxinsheng
@望星辰
全部源码地址: