新手练习,尝试使用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">&lsaquo;
  145. </a>
  146. <a class="carousel-control right" href="#myCarousel"
  147. data-slide="next">&rsaquo;
  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. // 获取dom元素 end
  74.  
  75. constructor(private renderer: Renderer,private http: Http) {
  76. // 初始:英雄列表隐藏
  77. this.statePanelExpression = 'close';
  78. // 初始:英雄详细隐藏
  79. this.stateHeroExpression = 'close';
  80. }
  81.  
  82. ngAfterViewInit() {
  83. // 初期设置大头像位置 start
  84. var selHeroDivHW = this.selHeroDivOut.nativeElement.clientWidth;
  85. var selHeroContainHeight = this.selHeroContain.nativeElement.clientHeight;
  86. var selHeroContainWidth = this.selHeroContain.nativeElement.clientWidth;
  87. var selHeroContainLeft = this.selHeroContain.nativeElement.offsetLeft;
  88. var selHeroContainTop = this.selHeroContain.nativeElement.offsetTop;
  89.  
  90. this.renderer.setElementStyle(this.selHeroDiv.nativeElement, 'width', selHeroDivHW+'px');
  91. this.renderer.setElementStyle(this.selHeroDiv.nativeElement, 'height', selHeroDivHW+'px');
  92. this.renderer.setElementStyle(this.selHeroDiv.nativeElement, 'left', selHeroContainLeft+(selHeroContainWidth-selHeroDivHW)*0.5 +'px');
  93. this.renderer.setElementStyle(this.selHeroDiv.nativeElement, 'top', selHeroContainTop+(selHeroContainHeight-selHeroDivHW)*0.5 +'px');
  94.  
  95. this.renderer.setElementStyle(this.selHeroDiv.nativeElement, 'display', 'block');
  96. // 初期设置大头像位置 end
  97. }
  98.  
  99. // 英雄列表面板显示隐藏控制 start
  100. statePanelExpression: string;
  101. showHeroListPanel() {
  102. this.renderer.setElementStyle(this.pullDown.nativeElement, 'display', 'none');
  103. this.statePanelExpression = 'open';
  104. this.renderer.setElementStyle(this.pullUp.nativeElement, 'display', 'block');
  105. this.renderer.setElementStyle(this.heroList.nativeElement, 'background', 'black');
  106. this.renderer.setElementStyle(this.hListMain.nativeElement, 'display', 'block');
  107. }
  108. hideHeroListPanel() {
  109. this.renderer.setElementStyle(this.pullUp.nativeElement, 'display', 'none');
  110. this.statePanelExpression = 'close';
  111. this.renderer.setElementStyle(this.pullDown.nativeElement, 'display', 'block');
  112. this.renderer.setElementStyle(this.heroList.nativeElement, 'background', 'gray');
  113. this.renderer.setElementStyle(this.hListMain.nativeElement, 'display', 'none');
  114. }
  115. showHideHeroListPanel(){
  116. if(this.statePanelExpression == 'close'){
  117. this.showHeroListPanel();
  118. }else{
  119. this.hideHeroListPanel();
  120. }
  121. }
  122. // 英雄列表面板显示隐藏控制 end
  123.  
  124. // 英雄列表 图阵 切换 start
  125. heroListLB(){
  126. this.renderer.setElementStyle(this.hListStyle2.nativeElement, 'display', 'none');
  127. this.renderer.setElementStyle(this.hListStyle1.nativeElement, 'display', 'block');
  128. this.showListTypeCur = "LB";
  129. }
  130. heroListTZ(){
  131. this.renderer.setElementStyle(this.hListStyle1.nativeElement, 'display', 'none');
  132. this.renderer.setElementStyle(this.hListStyle2.nativeElement, 'display', 'block');
  133. this.showListTypeCur = "TZ";
  134. }
  135. // 英雄列表 图阵 切换 end
  136.  
  137. // 抓取LOL服务器数据
  138. doGetHeroList(){
  139. this.renderer.setElementStyle(this.getHeroListDom.nativeElement, 'display', 'none');
  140. this.http.get('/getHeroList').toPromise().
  141. then(res =>
  142. {
  143. alert(res.text());
  144. this.renderer.setElementStyle(this.getHeroListDom.nativeElement, 'display', 'block');
  145. this.ngAfterViewInit();
  146. this.ngOnInit();
  147. }).catch((e)=>console.log(e));
  148. }
  149.  
  150. // 显示英雄详细信息 start
  151. stateHeroExpression: string;
  152. curHeroDataId = '';
  153. heroShowDetail:any = {};
  154. heroShowDetailPassive:any = {};
  155. heroShowDetailPassiveImg = '';
  156. heroShowDetailSkins : Array<any> = [];
  157. heroShowDetailSpells1 :any = {};
  158. heroShowDetailSpells2 :any = {};
  159. heroShowDetailSpells3 :any = {};
  160. heroShowDetailSpells4 :any = {};
  161. heroShowDetailAllytips : Array<any> = [];
  162. heroShowDetailEnemytips : Array<any> = [];
  163. showHeroDetail(heroData:any){
  164. // 获取英雄详细数据
  165. this.curHeroDataId = heroData.id;
  166. this.http.get('/' + this.curVer + '/'+ heroData.id +'.json').toPromise()
  167. .then((res:Response)=>{
  168. if(JSON.parse(res.text()).data.id == this.curHeroDataId){
  169. this.heroShowDetail = JSON.parse(res.text()).data;
  170. this.heroShowDetailSkins = JSON.parse(res.text()).data.skins;
  171. this.heroShowDetail.tags = this.heroTypeEC2C(this.heroShowDetail.tags);
  172. this.heroShowDetailPassive = JSON.parse(res.text()).data.passive;
  173. this.heroShowDetailPassiveImg = JSON.parse(res.text()).data.passive.image;
  174.  
  175. this.heroShowDetailSpells1 = JSON.parse(res.text()).data.spells[0];
  176. this.heroShowDetailSpells2 = JSON.parse(res.text()).data.spells[1];
  177. this.heroShowDetailSpells3 = JSON.parse(res.text()).data.spells[2];
  178. this.heroShowDetailSpells4 = JSON.parse(res.text()).data.spells[3];
  179. this.heroShowDetailSpells1.image = JSON.parse(res.text()).data.spells[0].image.full;
  180. this.heroShowDetailSpells2.image = JSON.parse(res.text()).data.spells[1].image.full;
  181. this.heroShowDetailSpells3.image = JSON.parse(res.text()).data.spells[2].image.full;
  182. this.heroShowDetailSpells4.image = JSON.parse(res.text()).data.spells[3].image.full;
  183. this.heroShowDetailAllytips = JSON.parse(res.text()).data.allytips;
  184. this.heroShowDetailEnemytips = JSON.parse(res.text()).data.enemytips;
  185. }
  186. }).catch(this.handleError);
  187. this.stateHeroExpression = 'open';
  188. }
  189. hideHeroDetail() {
  190. this.stateHeroExpression = 'close';
  191. }
  192. // 显示英雄详细信息 end
  193.  
  194. // 英雄列表所有版本号
  195. heroVers = JSON.parse('{}');
  196. heroDataList : Array<any> = [];
  197. bakHeroDataList : Array<any> = [];
  198. curVer = '';
  199. ngOnInit(){
  200. // 取得英雄列表所有版本号
  201. // console.log('client get hero version');
  202. this.loadingText = '开始取得英雄列表所有版本号';
  203. this.http.get('/getHeroVers').toPromise()
  204. .then((res:Response)=>{
  205. this.heroVers = this.extractVersData(res);
  206. if(!this.heroVers && !this.heroVers.vers){
  207. this.loadingText = '服务器尚未抓取英雄列表,请点击右上角文字抓取数据。';
  208. return;
  209. }
  210. this.curVer = (this.heroVers && this.heroVers.vers &&this.heroVers.vers.length>0)?this.heroVers.vers[0]:'';
  211. if(this.curVer!=''){
  212. // 获取英雄列表json
  213. this.loadingText = '开始取得英雄列表';
  214. this.http.get('/' + this.curVer + '/herolist.json').toPromise()
  215. .then((res:Response)=>{
  216. if(JSON.parse(res.text()).version == this.curVer){
  217. this.heroDataList = [];
  218. for (var key in JSON.parse(res.text()).keys) {
  219. var heroIdTmp = JSON.parse(res.text()).keys[key];
  220. this.heroDataList.push(
  221. JSON.parse(res.text()).data[heroIdTmp]
  222. );
  223. this.bakHeroDataList.push(
  224. JSON.parse(res.text()).data[heroIdTmp]
  225. );
  226. }
  227. for (var i = this.heroDataList.length - 1; i >= 0; i--) {
  228. this.heroDataList[i].tags = this.heroTypeEC2C(this.heroDataList[i].tags);
  229. this.bakHeroDataList[i].tags = this.heroTypeEC2C(this.bakHeroDataList[i].tags);
  230. }
  231. this.heroDataTypeList = this.heroDataList;
  232. this.loadingText = '随机生成对战英雄';
  233. this.genFight();
  234. this.loadingText = '加载完成';
  235. this.loadFinished = true;
  236. }
  237. }).catch(this.handleError);
  238. }else{
  239. this.loadingText = '服务器尚未抓取英雄列表,请点击右上角文字抓取数据。';
  240. }
  241. }).catch(this.handleError);
  242. }
  243.  
  244. genFight(){
  245. // 随机生成对战英雄
  246. var max = this.heroDataList.length;
  247. var randomI = Math.floor(Math.random()*max);
  248. this.leftPlayImg1 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
  249. var myHero = this.heroDataList[randomI];
  250. randomI = Math.floor(Math.random()*max);
  251. this.leftPlayImg2 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
  252. randomI = Math.floor(Math.random()*max);
  253. this.leftPlayImg3 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
  254. randomI = Math.floor(Math.random()*max);
  255. this.leftPlayImg4 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
  256. randomI = Math.floor(Math.random()*max);
  257. this.leftPlayImg5 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
  258. randomI = Math.floor(Math.random()*max);
  259. this.rightPlayImg1 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
  260. randomI = Math.floor(Math.random()*max);
  261. this.rightPlayImg2 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
  262. randomI = Math.floor(Math.random()*max);
  263. this.rightPlayImg3 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
  264. randomI = Math.floor(Math.random()*max);
  265. this.rightPlayImg4 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
  266. randomI = Math.floor(Math.random()*max);
  267. this.rightPlayImg5 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
  268. this.curHeroBigDataId = myHero.id;
  269. this.http.get('/' + this.curVer + '/'+ myHero.id +'.json').toPromise()
  270. .then((res:Response)=>{
  271. if(JSON.parse(res.text()).data.id == this.curHeroBigDataId){
  272. var max = JSON.parse(res.text()).data.skins.length;
  273. var randomI = Math.floor(Math.random()*max);
  274. this.styleExp = 'url("/'+this.curVer+'/skin/'
  275. +JSON.parse(res.text()).data.skins[randomI].id
  276. +'.jpg")';
  277. }
  278. }).catch(this.handleError);
  279. }
  280.  
  281. // 处理英雄列表所有版本号
  282. private extractVersData(res: Response) {
  283. let body = JSON.parse(res.text());
  284. if(body && body.vers){
  285. body.vers.sort((a : any,b : any)=>b>a); // 简单排序,需要加工
  286. }
  287. return body || { };
  288. }
  289. private handleError (error: Response | any) {
  290. console.error(error);
  291. return { };
  292. }
  293.  
  294. private heroTypeEC2C(ht:Array<string>): Array<string>{
  295. let result : Array<string> = [];
  296. for (var i = ht.length - 1; i >= 0; i--) {
  297. result.push(ht[i].replace('Mage','法师')
  298. .replace('Fighter','战士')
  299. .replace('Tank','坦克')
  300. .replace('Assassin','刺客')
  301. .replace('Marksman','射手')
  302. .replace('Support','辅助'));
  303. }
  304. return result;
  305. }
  306. removeTag(str:string):string{
  307. if(str)
  308. return str.replace(/<.*?>/ig,"");
  309. return '';
  310. }
  311.  
  312. curHeroBigDataId = '';
  313. showBigPic(heroData:any){
  314. // 修改大图像
  315. this.leftPlayImg1 = '/'+this.curVer+'/imgs/'+heroData.id+'.png';
  316. this.curHeroBigDataId = heroData.id;
  317. this.http.get('/' + this.curVer + '/'+ heroData.id +'.json').toPromise()
  318. .then((res:Response)=>{
  319. if(JSON.parse(res.text()).data.id == this.curHeroBigDataId){
  320. var max = JSON.parse(res.text()).data.skins.length;
  321. var randomI = Math.floor(Math.random()*max);
  322. this.styleExp = 'url("/'+this.curVer+'/skin/'
  323. +JSON.parse(res.text()).data.skins[randomI].id
  324. +'.jpg")';
  325. }
  326. }).catch(this.handleError);
  327. }
  328. heroDataTypeList : Array<any> = [];
  329. filterType(type:string):void{
  330. // 选择英雄类型
  331. this.heroTypeCCur = type;
  332. this.heroDataList = this.bakHeroDataList.filter(
  333. (hero:any)=>this.heroTypeCCur =='所有' || hero.tags.contains(this.heroTypeCCur));
  334. this.heroDataTypeList = this.heroDataList;
  335. }
  336. filterTypeFun(hero:any){
  337. return hero.tags.contains(this.heroTypeCCur);
  338. }
  339. searchHeroByName(value: string){
  340. // 过滤英雄名称
  341. this.heroDataList = this.heroDataTypeList.filter(
  342. (hero:any)=>value ==''
  343. || hero.id.toLowerCase().indexOf(value.toLowerCase())>=0
  344. || hero.name.toLowerCase().indexOf(value.toLowerCase())>=0
  345. || hero.title.toLowerCase().indexOf(value.toLowerCase())>=0);
  346. }
  347. tempVer = '';
  348. getNewVersion(ver: string){
  349. // 重新获取英雄版本
  350. this.tempVer = ver;
  351. if(this.tempVer!='')
  352. // 获取英雄列表json
  353. this.http.get('/' + this.tempVer + '/herolist.json').toPromise()
  354. .then((res:Response)=>{
  355. if(JSON.parse(res.text()).version == this.tempVer){
  356. this.heroDataList = [];
  357. for (var key in JSON.parse(res.text()).keys) {
  358. var heroIdTmp = JSON.parse(res.text()).keys[key];
  359. this.heroDataList.push(
  360. JSON.parse(res.text()).data[heroIdTmp]
  361. );
  362. this.bakHeroDataList.push(
  363. JSON.parse(res.text()).data[heroIdTmp]
  364. );
  365. }
  366. for (var i = this.heroDataList.length - 1; i >= 0; i--) {
  367. this.heroDataList[i].tags = this.heroTypeEC2C(this.heroDataList[i].tags);
  368. this.bakHeroDataList[i].tags = this.heroTypeEC2C(this.bakHeroDataList[i].tags);
  369. }
  370. this.heroDataTypeList = this.heroDataList;
  371. this.genFight();
  372. this.curVer = ver;
  373. this.heroTypeCCur = '所有';
  374. this.heroFilterName.nativeElement.value = '';
  375. }
  376. }).catch((error: Response | any)=>{
  377. alert('错误:找不到改版本信息');
  378. return {};
  379. });
  380. }
  381.  
  382. }

-----

中间效果图如下:

html模板制作:

抓取数据:

数据:

用angularjs2 绑定数据后:

首页:

列表:

详细:

检索:

没数据时:

转载请标明出处:cnblogs.com/wangxinsheng
@望星辰

全部源码地址:

http://download.csdn.net/user/wangxsh42

http://download.csdn.net/detail/wangxsh42/9737390

[nodejs,expressjs,angularjs2] LOL英雄列表数据抓取及查询显示应用的更多相关文章

  1. Android MaoZhuaWeiBo 好友动态信息列表数据抓取 -3

    前面2篇把大致的开发说的几乎相同了,接下来说说粉丝动态消息列表或时间线数据的抓取与解析显示,我将他所有写在了一个 类里.并以封装类对象的形式存储数据.以下看看基本的服务代码: 粉丝动态消息列表数据抓取 ...

  2. [原创.数据可视化系列之十二]使用 nodejs通过async await建立同步数据抓取

    做数据分析和可视化工作,最重要的一点就是数据抓取工作,之前使用Java和python都做过简单的数据抓取,感觉用的很不顺手. 后来用nodejs发现非常不错,通过js就可以进行数据抓取工作,类似jqu ...

  3. Phantomjs+Nodejs+Mysql数据抓取(2.抓取图片)

    概要 这篇博客是在上一篇博客Phantomjs+Nodejs+Mysql数据抓取(1.抓取数据) http://blog.csdn.net/jokerkon/article/details/50868 ...

  4. Phantomjs+Nodejs+Mysql数据抓取(1.数据抓取)

    概要: 这篇博文主要讲一下如何使用Phantomjs进行数据抓取,这里面抓的网站是太平洋电脑网估价的内容.主要是对电脑笔记本以及他们的属性进行抓取,然后在使用nodejs进行下载图片和插入数据库操作. ...

  5. Python数据抓取_BeautifulSoup模块的使用

    在数据抓取的过程中,我们往往都需要对数据进行处理 本篇文章我们主要来介绍python的HTML和XML的分析库 BeautifulSoup 的官方文档网站如下 https://www.crummy.c ...

  6. 网页数据抓取工具,webscraper 最简单的数据抓取教程,人人都用得上

    Web Scraper 是一款免费的,适用于普通用户(不需要专业 IT 技术的)的爬虫工具,可以方便的通过鼠标和简单配置获取你所想要数据.例如知乎回答列表.微博热门.微博评论.淘宝.天猫.亚马逊等电商 ...

  7. 大数据抓取采集框架(摘抄至http://blog.jobbole.com/46673/)

    摘抄至http://blog.jobbole.com/46673/ 随着BIG DATA大数据概念逐渐升温,如何搭建一个能够采集海量数据的架构体系摆在大家眼前.如何能够做到所见即所得的无阻拦式采集.如 ...

  8. python实现一个栏目的分页抓取列表页抓取

    python实现一个栏目的分页抓取列表页抓取 #!/usr/bin/env python # coding=utf-8 import requests from bs4 import Beautifu ...

  9. Python爬虫工程师必学——App数据抓取实战 ✌✌

    Python爬虫工程师必学——App数据抓取实战 (一个人学习或许会很枯燥,但是寻找更多志同道合的朋友一起,学习将会变得更加有意义✌✌) 爬虫分为几大方向,WEB网页数据抓取.APP数据抓取.软件系统 ...

随机推荐

  1. Python开发环境Wing IDE使用教程:部分调试功能介绍

    下面是用户应该了解的Wing IDE的其它一些调试功能: Main Debug File—用户可以指定项目中的一个文件作为调试的主入口点.当完成这个设置之后,调试总是从这个文件开始,除非用户使用Deb ...

  2. JQUERY 插件开发——MENU(导航菜单)

    JQUERY 插件开发——MENU(导航菜单) 故事背景:由于最近太忙了,已经很久没有写jquery插件开发系列了.但是凭着自己对这方面的爱好,我还是抽了一些时间来过一下插件瘾的.今天的主题是导航菜单 ...

  3. RPC服务的发布订阅实现Thrift

    Thrift 个人实战--RPC服务的发布订阅实现(基于Zookeeper服务) 前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的 ...

  4. (转)C++重写、重载和重定义的区别

    C++ 重写重载重定义区别 (源自:http://blog.163.com/clevertanglei900@126/blog/static/111352259201102441934870/) 1 ...

  5. 企业架构研究总结(28)——TOGAF架构开发方法(ADM)之需求管理阶段

    1.11 需求管理(Requirements Management) 企业架构开发方法各阶段——需求管理 1.11.1 目标 本阶段的目标是定义一个过程,使企业架构的需求可以被识别.存储并与其他架构开 ...

  6. DevExpress 学习使用之 Skin

    新建了一个XtraForm,设置属性里的皮肤属性却不能实现,群里朋友发过来一个简单的换肤项目 1. 先觉条件似乎是窗体应该继承“public partial class XtraForm1 : Dev ...

  7. 搭建一个完整的Java开发环境

    搭建一个完整的Java开发环境 作为一个Java程序员,配置一个java开发环境是必备的技能,今天给广大菜鸟初学者补上一课.环境的配置,大概就分三个1,JDK 2,Tomcat(或者其他的)3,ecl ...

  8. c:forEach 实现换行

    Map<String,String> map = new TreeMap<String,String>(); map.put("key1", "v ...

  9. ngx-push-stream模块源码学习(五)——内存清理

    1.定时器         采用nginx自身的定时器管理机制,具体细节待学习过nginx源码后加以补充 2.channel的生成周期 (0).初始(诞生)         发布.订阅均有可能产生ch ...

  10. SVN Access to '/svn/Test/!svn/me' forbidden,不能更新解决办法

    从之前的电脑将Repositorise复制到现在用的PC,出现可以checkout但是不能update的问题.在网上找到以下解决方法,均未能解决. 1.确认URL跟实际一致: 2.确认用户名密码正确: ...