[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:
- {
- "name": "lol_Heros",
- "version": "1.0.0",
- "description": "get and show lolHeros from qq with NodeJS-Server,ExpressJS-RouteAndTemplate,AngularJS2-JSFrontFramework,Bootstrap-CSS",
- "private": true,
- "keywords": [
- "lol",
- "Heros"
- ],
- "author": "Wang Xinsheng",
- "license": "MIT",
- "scripts": {
- "start": "tsc && concurrently \"tsc -w\" \"supervisor ./bin/www\" ",
- "tsc": "tsc",
- "tsc:w": "tsc -w"
- },
- "dependencies": {
- "@angular/common": "~2.4.0",
- "@angular/compiler": "~2.4.0",
- "@angular/core": "~2.4.0",
- "@angular/forms": "~2.4.0",
- "@angular/http": "~2.4.0",
- "@angular/platform-browser": "~2.4.0",
- "@angular/platform-browser-dynamic": "~2.4.0",
- "@angular/router": "~3.4.0",
- "@types/jquery": "^2.0.39",
- "angular-in-memory-web-api": "~0.2.4",
- "body-parser": "~1.15.2",
- "cookie-parser": "~1.4.3",
- "core-js": "^2.4.1",
- "debug": "~2.2.0",
- "express": "~4.14.0",
- "jade": "~1.11.0",
- "morgan": "~1.7.0",
- "rxjs": "5.0.1",
- "serve-favicon": "~2.3.0",
- "sync-request": "~3.0.1",
- "systemjs": "0.19.40",
- "zone.js": "^0.7.4"
- },
- "devDependencies": {
- "concurrently": "^3.1.0",
- "typescript": "~2.0.10",
- "tslint": "^3.15.1",
- "@types/node": "^6.0.46"
- }
- }
Express路由:省略,详细可查看附件
Nodejs 抓取数据代码(getHeroList.js):
- /* GET Hreo List Data. */
- /*写入文件系统*/
- var fs= require('fs');
- var path = require('path');
- /*同步抓取*/
- var request = require('sync-request');
- // 所有英雄列表
- var heroListPath = 'http://lol.qq.com/biz/hero/champion.js';
- // 单图 image full:http://ossweb-img.qq.com/images/lol/img/champion/Aatrox.png
- var fullImgPath = 'http://ossweb-img.qq.com/images/lol/img/champion/';
- //英雄信息:Aatrox=data.ID.js
- var heroDetailPath = 'http://lol.qq.com/biz/hero/';
- // skins.id http://ossweb-img.qq.com/images/lol/web201310/skin/big266000.jpg
- var heroDetailSkinPath = 'http://ossweb-img.qq.com/images/lol/web201310/skin/big';
- // 技能:Aatrox_Passive.png=>http://ossweb-img.qq.com/images/lol/img/passive/Aatrox_Passive.png
- var heroDetailPSkillPath = 'http://ossweb-img.qq.com/images/lol/img/passive/';
- // Q技能:http://ossweb-img.qq.com/images/lol/img/spell/AatroxQ.png Aatrox.png
- var heroDetailSkillPath = 'http://ossweb-img.qq.com/images/lol/img/spell/';
- var heroVerPath = '';
- var heroVerSkinPath = '';
- var heroVerSkillPath = '';
- var heroVerImgPath = '';
- var heroListJson = null;
- module.exports = function() {
- console.log('GET Hreo List Data starting...');
- // 新建文件夹
- // process.cwd() 启动目录
- // process.execPath node.exe文件路劲
- // __dirname 代码所在的目录
- var heroDataPath = process.cwd() + '\\heroData';
- var exists = fs.existsSync(heroDataPath);
- if(!exists){
- // 不存在创建目录
- try{
- fs.mkdirSync(heroDataPath);
- console.log('创建目录成功:'+heroDataPath);
- }catch(e){
- console.log('创建目录失败',heroDataPath,e);
- return '创建目录失败:'+'\n'+heroDataPath+'\n'+e;
- }
- }
- // 抓取数据-所有英雄
- var r = getHList(heroDataPath);
- if(r!='')
- return r;
- // 抓取数据-所有英雄小头像
- var r = getHListImg();
- if(r!=''){
- deleteFolderRecursive(heroVerPath);
- return r;
- }
- console.log('GET Hreo List Data Finished');
- return '';
- };
- // 获取英雄列表,英雄版本重复检查,创建版本文件夹,写入英雄列表
- function getHList(parentPath){
- console.log('GET Hreo List Data...');
- var opt = getRequireOption(heroListPath);
- var res = request(opt.method,opt.path,opt);
- var data = res.getBody("utf8");
- // jsonp 解析
- data = data.replace('if(!LOLherojs)var LOLherojs={};LOLherojs.champion=','');
- data = data.substr(0 ,data.length-1);
- data = reconvert(data);
- heroListJson = JSON.parse(data);
- console.log(heroListJson.version,heroListJson.updated);
- //JSON.stringify(obj)
- heroVerPath = parentPath + '\\'+heroListJson.version;
- var exists = fs.existsSync(heroVerPath);
- if(exists){
- console.log('存在该版本',heroListJson.version);
- return '存在该版本';
- }else{
- try{
- fs.mkdirSync(heroVerPath);
- }catch(e){
- console.log('创建目录失败',heroVerPath,e);
- return '创建目录失败:'+"\n"+heroVerPath+"\n"+e;
- }
- var heroVerListPath = heroVerPath + '\\herolist.json';
- try{
- var w = fs.writeFileSync(heroVerListPath, JSON.stringify(heroListJson));
- }catch(e){
- console.log('写入错误',heroVerListPath,e);
- return '写入错误:'+"\n"+heroVerListPath+"\n"+e;
- }
- console.log('写入成功',heroVerListPath);
- }
- console.log('GET Hreo List Data Finished');
- return '';
- }
- function getHListImg(){
- // 抓取图片
- // 创建头像目录
- heroVerImgPath = heroVerPath + "\\" + "imgs";
- var exists = fs.existsSync(heroVerImgPath);
- if(!exists){
- // 不存在创建目录
- try{
- fs.mkdirSync(heroVerImgPath);
- console.log('创建目录成功:'+heroVerImgPath);
- }catch(e){
- console.log('创建目录失败',heroVerImgPath,e);
- return '创建目录失败:'+'\n'+heroVerImgPath+'\n'+e;
- }
- }
- // 皮肤目录
- heroVerSkinPath = heroVerPath + "\\" + "skin";
- var exists = fs.existsSync(heroVerSkinPath);
- if(!exists){
- // 不存在创建目录
- try{
- fs.mkdirSync(heroVerSkinPath);
- console.log('创建目录成功:'+heroVerSkinPath);
- }catch(e){
- console.log('创建目录失败',heroVerSkinPath,e);
- return '创建目录失败:'+'\n'+heroVerSkinPath+'\n'+e;
- }
- }
- // 技能目录
- heroVerSkillPath = heroVerPath + "\\" + "skill";
- var exists = fs.existsSync(heroVerSkillPath);
- if(!exists){
- // 不存在创建目录
- try{
- fs.mkdirSync(heroVerSkillPath);
- console.log('创建目录成功:'+heroVerSkillPath);
- }catch(e){
- console.log('创建目录失败',heroVerSkillPath,e);
- return '创建目录失败:'+'\n'+heroVerSkillPath+'\n'+e;
- }
- }
- for (var key in heroListJson.keys) {
- // 下载头像图片
- var imgName = heroListJson.data[heroListJson.keys[key]].image.full;
- var fullImgUrl = fullImgPath+imgName;
- console.log("抓取头像图片",imgName,fullImgUrl);
- var opt = getRequireOption(fullImgUrl);
- var res = request(opt.method,opt.path,opt);
- var data = res.getBody();
- var heroVerFullImgPath = heroVerImgPath + '\\'+imgName;
- try{
- var w = fs.writeFileSync(heroVerFullImgPath, data);
- }catch(e){
- console.log('写入错误',heroVerFullImgPath,e);
- return '写入错误:'+"\n"+heroVerFullImgPath+"\n"+e;
- }
- console.log('写入成功',heroVerFullImgPath);
- // 下载英雄详细文件
- var heroDataId = heroListJson.keys[key];
- var heroDataUrl = heroDetailPath+heroDataId+'.js';
- console.log("抓取英雄详细数据",heroDataId,heroDataUrl);
- var opt = getRequireOption(heroDataUrl);
- var res = request(opt.method,opt.path,opt);
- var data = res.getBody('utf8');
- // jsonp 解析
- data = data.replace('if(!LOLherojs)var LOLherojs={champion:{}};LOLherojs.champion.'+heroDataId+'=','');
- data = data.substr(0 ,data.length-1);
- data = reconvert(data);
- var heroDetailJson = JSON.parse(data);
- var heroVerDetailPath = heroVerPath + '\\'+heroDataId+'.json';
- try{
- var w = fs.writeFileSync(heroVerDetailPath, data);
- }catch(e){
- console.log('写入错误',heroVerDetailPath,e);
- return '写入错误:'+"\n"+heroVerDetailPath+"\n"+e;
- }
- console.log('写入成功',heroVerDetailPath);
- // 下载英雄皮肤图片
- for(var skin in heroDetailJson.data.skins){
- skin = heroDetailJson.data.skins[skin];
- var skinImgUrl = heroDetailSkinPath + skin.id + '.jpg';
- console.log("抓取皮肤图片",skin.id,skinImgUrl);
- var opt = getRequireOption(skinImgUrl);
- var res = request(opt.method,opt.path,opt);
- var data = res.getBody();
- var heroVerSkinImgPath = heroVerSkinPath + '\\'+skin.id + '.jpg';
- try{
- var w = fs.writeFileSync(heroVerSkinImgPath, data);
- }catch(e){
- console.log('写入错误',heroVerSkinImgPath,e);
- return '写入错误:'+"\n"+heroVerSkinImgPath+"\n"+e;
- }
- console.log('写入成功',heroVerSkinImgPath);
- }
- // 下载英雄技能图片 主动
- for(var spell in heroDetailJson.data.spells){
- spell = heroDetailJson.data.spells[spell];
- var spellImgUrl = heroDetailSkillPath + spell.image.full;
- console.log("抓取主动技能图片",spell.image.full,spellImgUrl);
- var opt = getRequireOption(spellImgUrl);
- var res = request(opt.method,opt.path,opt);
- var data = res.getBody();
- var heroVerSpellImgPath = heroVerSkillPath + '\\'+spell.image.full;
- try{
- var w = fs.writeFileSync(heroVerSpellImgPath, data);
- }catch(e){
- console.log('写入错误',heroVerSpellImgPath,e);
- return '写入错误:'+"\n"+heroVerSpellImgPath+"\n"+e;
- }
- console.log('写入成功',heroVerSpellImgPath);
- }
- // 下载英雄技能图片 被动
- var passiveImgUrl = heroDetailPSkillPath + heroDetailJson.data.passive.image.full;
- console.log("抓取被动技能图片",heroDetailJson.data.passive.image.full,passiveImgUrl);
- var opt = getRequireOption(passiveImgUrl);
- var res = request(opt.method,opt.path,opt);
- var data = res.getBody();
- var heroVerPassiveImgPath = heroVerSkillPath + '\\'+heroDetailJson.data.passive.image.full;
- try{
- var w = fs.writeFileSync(heroVerPassiveImgPath, data);
- }catch(e){
- console.log('写入错误',heroVerPassiveImgPath,e);
- return '写入错误:'+"\n"+heroVerPassiveImgPath+"\n"+e;
- }
- console.log('写入成功',heroVerPassiveImgPath);
- //break; //test
- }
- return '';
- }
- function reconvert(str){
- str = str.replace(/(\\u)(\w{1,4})/gi,function($0){
- return (String.fromCharCode(parseInt((escape($0).replace(/(%5Cu)(\w{1,4})/g,"$2")),16)));
- });
- str = str.replace(/(&#x)(\w{1,4});/gi,function($0){
- return String.fromCharCode(parseInt(escape($0).replace(/(%26%23x)(\w{1,4})(%3B)/g,"$2"),16));
- });
- str = str.replace(/(&#)(\d{1,6});/gi,function($0){
- return String.fromCharCode(parseInt(escape($0).replace(/(%26%23)(\d{1,6})(%3B)/g,"$2")));
- });
- return str;
- }
- function deleteFolderRecursive(path) {
- var files = [];
- if( fs.existsSync(path) ) {
- files = fs.readdirSync(path);
- files.forEach(function(file,index){
- var curPath = path + "/" + file;
- if(fs.statSync(curPath).isDirectory()) { // recurse
- deleteFolderRecursive(curPath);
- } else { // delete file
- fs.unlinkSync(curPath);
- }
- });
- fs.rmdirSync(path);
- }
- };
- function getRequireOption(pathStr){
- return op={
- host:pathStr.match(/http[s]?:\/\/[^\\|\/]*/)[0].replace(/http[s]?:\/\//,''),
- port:80,
- method:'GET',
- path:pathStr,
- headers:{
- 'Host':pathStr.match(/http[s]?:\/\/[^\\|\/]*/)[0].replace(/http[s]?:\/\//,''),
- "User-Agent":"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.92 Safari/537.1 LBBROWSER",
- "Referer":pathStr.match(/http[s]?:\/\/[^\\|\/]*/)[0].replace(/http[s]?:\/\//,'')
- }
- }
- }
jade模板代码(indexTemplate.jade):
- doctype html
- html
- head
- title LOL英雄
- script(src='/javascripts/jquery-3.1.1.min.js')
- script(src='/javascripts/bootstrap.min.js')
- script(src='/core-js/client/shim.min.js')
- script(src='/zone.js/dist/zone.js')
- script(src='/jade/jade.js')
- script(src='/systemjs/dist/system.src.js')
- script(src='/javascripts/systemjs.config.js')
- script.
- System.import('app').catch(function(err){ console.error(err); });
- link(href='/stylesheets/bootstrap.min.css', rel='stylesheet')
- style.
- html,body{background-color: black;color:rgb(255,215,000); overflow: hidden; height:100%;}
- .main,.selHeroMain{
- width:100%;height:100%;
- }
- .selHeroContain{
- border-radius: 50%;
- border:3px rgb(255,215,000) solid;
- width:60%;
- height:90%;
- margin: 0 auto;
- }
- .selHeroDivOut{
- border:1px black solid;
- width:50%;
- height:300%;
- margin: auto;
- margin-top: -50%;
- background-color: black;
- }
- .selHeroDiv{
- position:absolute;
- display: none;
- border-radius: 50%;
- border:2px rgb(255,215,000) solid;
- background-size:196% 100%;
- background-repeat:no-repeat;
- background-position:100% 100%;
- overflow: hidden;
- box-shadow: 0px 0px 30px rgb(255,215,000);
- }
- .selHeroDiv img{
- height:100%;
- border-radius: 50%;
- }
- .leftHeros,.rightHeros{
- width:15%;
- height:90%;
- position:absolute;
- top:0px;
- overflow: hidden;
- }
- .leftHeros{
- left:0px;
- }
- .rightHeros{
- right:0px;
- }
- .leftHeros ul,.rightHeros ul{
- height:90%;
- margin-top: 30%;
- padding-left: 0px;
- }
- .leftHeros li,.rightHeros li{
- white-space:nowrap;
- font-size:20px;
- list-style-type:none;
- height:18%;
- padding:1% 0;
- border-bottom: 1px rgb(255,215,000) solid;
- overflow: hidden;
- }
- .leftHeros li{
- text-align: left;
- }
- .rightHeros li{
- text-align: right;
- }
- .leftHeros img,.rightHeros img{
- vertical-align: bottom;
- height:100%;
- overflow: hidden;
- }
- .leftHeros span,.rightHeros span{
- overflow: hidden;
- }
- /* css3实现图片划过一束光闪过效果 */
- .selHeroDiv:before {
- content: ""; position: absolute; width:200px; height: 100%; top: 0; left: -350px; overflow: hidden;
- background: -moz-linear-gradient(left, rgba(255,255,255,0)0, rgba(255,255,255,.2)50%, rgba(255,255,255,0)100%);
- 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)));
- background: -webkit-linear-gradient(left, rgba(255,255,255,0)0, rgba(255,255,255,.2)50%, rgba(255,255,255,0)100%);
- background: -o-linear-gradient(left, rgba(255,255,255,0)0, rgba(255,255,255,.2)50%, rgba(255,255,255,0)100%);
- -webkit-transform: skewX(-25deg);
- -moz-transform: skewX(-25deg);
- animation:selHeroDivAnimate 9s infinite linear;
- }
- .selHeroDiv:hover:before { left: 150%; animation:selHeroDivAnimateHover 1s 1 ease 0s; /*transition: left 1s ease 0s;*/}
- @keyframes selHeroDivAnimate
- {
- 0% {left: -350px;}
- 90% {left: -350px;}
- 100% {left: 150%;}
- }
- @keyframes selHeroDivAnimateHover
- {
- 0% {left: -350px;}
- 100% {left: 150%;}
- }
- .pullDown{
- width:100%;
- height:10%;
- position:absolute;
- top:0px;
- text-align: center;
- vertical-align: middle;
- font-size: 50px;
- color:white;
- cursor:pointer;
- }
- .pullDown span{width:100%;position: absolute;top: 0px;left:0px;animation:pullDown 2s infinite linear;}
- @keyframes pullDown
- {
- 0% {top: 0px;}
- 50% {top: 20px;}
- 100% {top: 0px;}
- }
- .heroList{
- width:100%;
- height:60%;
- position:absolute;
- opacity:0.2;
- background: gray;
- top:90%;
- }
- /*.heroList:hover{
- opacity:1;
- background: black;
- top:40%;
- transition: opacity,top 1s ease 0s;
- }*/
- .pullUp{
- position:relative;
- top:0px;
- color:white;
- text-align: right;
- display: none;
- cursor:pointer;
- }
- .hListMain{display: none; height: 95%;}
- .hListSearchBar{height: 10%;}
- .hListStyle1,.hListStyle2{vertical-align: middle; font-size: 30px; height:85%; overflow-y: auto; overflow-x: hidden;}
- .hListStyle1 .row,.hListStyle2 .row{ margin-top: 15px; border-bottom: 1px rgb(255,215,000) solid; }
- .hListStyle1 .row{cursor: pointer;}
- .hListStyle2 .row{border: none;}
- .hListStyle1 .row div{ height: 100px; line-height: 100px;}
- .hListStyle2 .row {width:70%; margin:0 auto;}
- .hListStyle2 .row div{cursor: pointer;}
- .hListStyle2{display: none;}
- .hero{position: absolute;width:80%; border: 1px rgb(255,215,000) solid;top:-100%;
- border-radius: 30px; top:10%;left:10%;background: #2B2B2B; font-size: 30px; height: 80%; /*display: none;*/}
- .heroTitle{height:20%;width:100%;}
- .heroData{overflow-y: auto; overflow-x: hidden;height:75%;width:100%;font-size: 15px;}
- .heroData .row{margin-bottom: 5px; }
- .heroClose{color:white; font-size: 10px; cursor: pointer;}
- .getHeroList{position: absolute;top:0px; right: 0px; color: black;font-style: 13px;cursor: pointer;z-index:99;}
- .leftHeros li:first-child img{border:1px rgb(255,215,000) solid}
- .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);}
- body
- script.
- window.onresize = function(){
- var selHeroDivHW = $(".selHeroDivOut").width();
- $(".selHeroDiv").width(selHeroDivHW);
- $(".selHeroDiv").height(selHeroDivHW);
- $(".selHeroDiv").offset({"left":$(".selHeroContain").offset().left+($(".selHeroContain").width()-selHeroDivHW)*0.5
- ,"top":$(".selHeroContain").offset().top+($(".selHeroContain").height()-selHeroDivHW)*0.5});
- $(".selHeroDiv").show();
- };
- function stopPropagation(e){
- window.event? window.event.cancelBubble = true : e.stopPropagation();
- }
- Array.prototype.contains=function(obj) {
- var index=this.length;
- while (index--){
- if(this[index]===obj){
- return true;
- }
- }
- return false;
- }
- .main
Angularjs2 模板代码(selectHero.html)【理论上应该分组件,通过组件父子间通信来完成】:
- <div class='selHeroMain' (mousewheel)="showHideHeroListPanel()" >
- <div class='selHeroContain' #selHeroContain>
- <div class='selHeroDivOut' #selHeroDivOut>
- <div class='selHeroDiv' [ngStyle]="{'background-image': styleExp}" #selHeroDiv>
- </div>
- </div>
- </div>
- <div class='leftHeros'>
- <ul>
- <li>玩家1:<span><img src='{{leftPlayImg1}}' width='133' height='120' /></span></li>
- <li>玩家2:<span><img src='{{leftPlayImg2}}' width='133' height='120' /></span></li>
- <li>玩家3:<span><img src='{{leftPlayImg3}}' width='133' height='120' /></span></li>
- <li>玩家4:<span><img src='{{leftPlayImg4}}' width='133' height='120' /></span></li>
- <li>玩家5:<span><img src='{{leftPlayImg5}}' width='133' height='120' /></span></li>
- </ul>
- </div>
- <div class='rightHeros'>
- <ul>
- <li><span><img src='{{rightPlayImg1}}' width='133' height='120' />:玩家1</span></li>
- <li><span><img src='{{rightPlayImg2}}' width='133' height='120' />:玩家2</span></li>
- <li><span><img src='{{rightPlayImg3}}' width='133' height='120' />:玩家3</span></li>
- <li><span><img src='{{rightPlayImg4}}' width='133' height='120' />:玩家4</span></li>
- <li><span><img src='{{rightPlayImg5}}' width='133' height='120' />:玩家5</span></li>
- </ul>
- </div>
- <!--<div class='pullDown'><span>下拉/点击 选择英雄</span></div>-->
- </div>
- <div class='heroList container' [@openClosePanel]="statePanelExpression" #heroList >
- <div class='pullDown' (click)="showHeroListPanel()" #pullDown ><span>下拉/点击 选择英雄</span></div>
- <div class='pullUp' (click)="hideHeroListPanel()" #pullUp >关闭</div>
- <div class='hListMain' #hListMain >
- <div class='hListSearchBar form-inline text-center'>
- <div class="row">
- <div class="col-lg-1 col-md-1 col-sm-1">
- <div class="dropdown">
- <button type="button" class="btn dropdown-toggle btn-primary" id="dropdownMenuVer" data-toggle="dropdown">版本
- <span class="caret"></span>
- </button>
- <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenuVer">
- <li role="presentation" *ngFor="let ver of heroVers.vers; let i = index" [ngClass]="{'active':ver==curVer}" (click)="getNewVersion(ver)">
- <a role="menuitem" tabindex="-1" href="#" >{{ver}}</a>
- </li>
- </ul>
- </div>
- </div>
- <div class="col-lg-1 col-md-1 col-sm-1">
- <div class="dropdown">
- <button type="button" class="btn dropdown-toggle btn-primary" id="dropdownMenuVer" data-toggle="dropdown">英雄类型
- <span class="caret"></span>
- </button>
- <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenuVer">
- <li role="presentation" *ngFor="let htc of heroTypeCList; let i = index" [ngClass]="{'active':htc==heroTypeCCur}" (click)="filterType(heroTypeCList[i])">
- <a role="menuitem" tabindex="-1" href="#">{{heroTypeCList[i]}}</a>
- </li>
- </ul>
- </div>
- </div>
- <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>
- <div class="col-lg-8 col-md-8 col-sm-8">检索条件: {{heroTypeCCur}}英雄 | 名称:{{heroFilterName.value}}</div>
- <div class="col-lg-1 col-md-1 col-sm-1">
- <div class="dropdown pull-right">
- <button type="button" class="btn dropdown-toggle btn-primary" id="dropdownMenuVer" data-toggle="dropdown">显示方式
- <span class="caret"></span>
- </button>
- <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenuVer">
- <li role="presentation" [ngClass]="{'active':showListTypeCur=='LB'}">
- <a role="menuitem" tabindex="-1" href="#" #menuitemLB (click)="heroListLB()" >列表</a>
- </li>
- <li role="presentation" [ngClass]="{'active':showListTypeCur=='TZ'}">
- <a role="menuitem" tabindex="-1" href="#" #menuitemTZ (click)="heroListTZ()" >图阵</a>
- </li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- <div class='hListStyle1' #hListStyle1 >
- <div class="row text-center" (click)="showHeroDetail(heroData)" (mouseenter)="showBigPic(heroData)" *ngFor="let heroData of heroDataList; let i = index">
- <div class="col-lg-1 col-md-1 col-sm-1">
- </div>
- <div class="col-lg-2 col-md-2 col-sm-2">
- <img src='/{{curVer}}/imgs/{{heroData.image.full}}' width="90" />
- </div>
- <div class="col-lg-1 col-md-1 col-sm-1">
- {{heroData.id}}
- </div>
- <div class="col-lg-2 col-md-2 col-sm-2">
- {{heroData.name}}
- </div>
- <div class="col-lg-2 col-md-2 col-sm-2">
- {{heroData.title}}
- </div>
- <div class="col-lg-2 col-md-2 col-sm-2">
- {{heroData.tags}}
- </div>
- <div class="col-lg-2 col-md-2 col-sm-2">
- </div>
- </div>
- </div>
- <div class='hListStyle2' #hListStyle2 >
- <div class="row text-center">
- <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">
- <a data-toggle="tooltip" data-placement="top" title="{{heroData.id}}:{{heroData.name}}:{{heroData.title}}:{{heroData.tags}}">
- <img src='/{{curVer}}/imgs/{{heroData.image.full}}' width="120" />
- </a>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div *ngIf="heroShowDetailAllytips && heroShowDetailAllytips.length>0" class='hero container' [@openCloseHero]="stateHeroExpression" #hero >
- <p class="heroClose text-right" (click)="hideHeroDetail()" >关闭</p>
- <div class="heroTitle">
- <div class="row">
- <div class="col-lg-2 col-md-2 col-sm-2">
- <img src='/{{curVer}}/imgs/{{heroShowDetail.id}}.png' width="120" />
- </div>
- <div class="col-lg-6 col-md-6 col-sm-6">
- ({{heroShowDetail.id}}) {{heroShowDetail.name}} : {{heroShowDetail.title}}
- </div>
- <div class="col-lg-2 col-md-2 col-sm-2 text-right">
- <span class="badge">[{{heroShowDetail.tags}}]</span>
- </div>
- </div>
- </div>
- <div class="heroData">
- <div class="row">
- <div class="col-lg-2 col-md-2 col-sm-2"></div>
- <div class="col-lg-8 col-md-8 col-sm-8">
- <div id="myCarousel" class="carousel slide" #myCarousel>
- <!-- 轮播(Carousel)指标 -->
- <ol class="carousel-indicators">
- <li data-target="#myCarousel" [ngClass]="{'active':i==0}" *ngFor="let skin of heroShowDetailSkins; let i = index" ></li>
- </ol>
- <!-- 轮播(Carousel)项目 -->
- <div class="carousel-inner">
- <div class="item" [ngClass]="{'active':i==0}" *ngFor="let skin of heroShowDetailSkins; let i = index" >
- <img src="/{{curVer}}/skin/{{skin.id}}.jpg" alt="{{skin.name}}">
- <div class="carousel-caption">{{skin.name}}</div>
- </div>
- </div>
- <!-- 轮播(Carousel)导航 -->
- <a class="carousel-control left" href="#myCarousel"
- data-slide="prev">‹
- </a>
- <a class="carousel-control right" href="#myCarousel"
- data-slide="next">›
- </a>
- </div>
- </div>
- <div class="col-lg-2 col-md-2 col-sm-2"></div>
- </div>
- <div class="row">
- <div class="col-lg-1 col-md-1 col-sm-1"></div>
- <div class="col-lg-1 col-md-1 col-sm-1">故事
- </div>
- <div class="col-lg-10 col-md-10 col-sm-10">
- </div>
- </div>
- <div class="row">
- <div class="col-lg-2 col-md-2 col-sm-2"></div>
- <div class="col-lg-8 col-md-8 col-sm-8">{{heroShowDetail.lore}}
- </div>
- <div class="col-lg-2 col-md-2 col-sm-2"></div>
- </div>
- <div class="row">
- <div class="col-lg-1 col-md-1 col-sm-1"></div>
- <div class="col-lg-1 col-md-1 col-sm-1">技能
- </div>
- <div class="col-lg-10 col-md-10 col-sm-10">
- </div>
- </div>
- <div class="row">
- <div class="col-lg-2 col-md-2 col-sm-2"></div>
- <div class="col-lg-1 col-md-1 col-sm-1"><img src='/{{curVer}}/skill/{{heroShowDetailPassiveImg.full}}' width="80" /></div>
- <div class="col-lg-7 col-md-7 col-sm-7">
- {{heroShowDetailPassive.name}}<br/>{{heroShowDetailPassive.description}}
- </div>
- <div class="col-lg-2 col-md-2 col-sm-2"></div>
- </div>
- <div class="row">
- <div class="col-lg-2 col-md-2 col-sm-2"></div>
- <div class="col-lg-1 col-md-1 col-sm-1"><img src='/{{curVer}}/skill/{{heroShowDetailSpells1.image}}' width="80" /></div>
- <div class="col-lg-3 col-md-3 col-sm-3">
- {{heroShowDetailSpells1.id}}<br/>
- {{heroShowDetailSpells1.name}}<br/>
- {{heroShowDetailSpells1.description}}<br/>
- {{removeTag(heroShowDetailSpells1.tooltip)}}
- </div>
- <div class="col-lg-1 col-md-1 col-sm-1"><img src='/{{curVer}}/skill/{{heroShowDetailSpells2.image}}' width="80" /></div>
- <div class="col-lg-3 col-md-3 col-sm-3">
- {{heroShowDetailSpells2.id}}<br/>
- {{heroShowDetailSpells2.name}}<br/>
- {{heroShowDetailSpells2.description}}<br/>
- {{removeTag(heroShowDetailSpells2.tooltip)}}
- </div>
- <div class="col-lg-2 col-md-2 col-sm-2"></div>
- </div>
- <div class="row">
- <div class="col-lg-2 col-md-2 col-sm-2"></div>
- <div class="col-lg-1 col-md-1 col-sm-1"><img src='/{{curVer}}/skill/{{heroShowDetailSpells3.image}}' width="80" /></div>
- <div class="col-lg-3 col-md-3 col-sm-3">
- {{heroShowDetailSpells3.id}}<br/>
- {{heroShowDetailSpells3.name}}<br/>
- {{heroShowDetailSpells3.description}}<br/>
- {{removeTag(heroShowDetailSpells3.tooltip)}}
- </div>
- <div class="col-lg-1 col-md-1 col-sm-1"><img src='/{{curVer}}/skill/{{heroShowDetailSpells4.image}}' width="80" /></div>
- <div class="col-lg-3 col-md-3 col-sm-3">
- {{heroShowDetailSpells4.id}}<br/>
- {{heroShowDetailSpells4.name}}<br/>
- {{heroShowDetailSpells4.description}}<br/>
- {{removeTag(heroShowDetailSpells4.tooltip)}}
- </div>
- <div class="col-lg-2 col-md-2 col-sm-2"></div>
- </div>
- <div class="row">
- <div class="col-lg-1 col-md-1 col-sm-1"></div>
- <div class="col-lg-1 col-md-1 col-sm-1">技巧
- </div>
- <div class="col-lg-10 col-md-10 col-sm-10">
- </div>
- </div>
- <div class="row">
- <div class="col-lg-2 col-md-2 col-sm-2"></div>
- <div class="col-lg-1 col-md-1 col-sm-1">己方技巧:</div>
- <div class="col-lg-7 col-md-7 col-sm-7">
- <div class="row" *ngFor="let str of heroShowDetailAllytips; let i = index">{{str}}</div>
- </div>
- <div class="col-lg-2 col-md-2 col-sm-2"></div>
- </div>
- <div class="row">
- <div class="col-lg-2 col-md-2 col-sm-2"></div>
- <div class="col-lg-1 col-md-1 col-sm-1">敌方技巧:</div>
- <div class="col-lg-7 col-md-7 col-sm-7">
- <div class="row" *ngFor="let str of heroShowDetailEnemytips; let i = index">{{str}}</div>
- </div>
- <div class="col-lg-2 col-md-2 col-sm-2"></div>
- </div>
- </div>
- </div>
- <div class="getHeroList" #getHeroList (click)="doGetHeroList()" [style.color]="loadFinished?'black':'gold'">点此抓取LOL英雄列表 ^-^</div>
- <div class='loadingDiv' [style.display]="loadFinished?'none':'block'">{{loadingText}}</div>
Angularjs2 ts代码(app.component.ts):
- import {Component, OnInit, ViewChild, Renderer, ElementRef, AfterViewInit, animate, trigger,state,style,transition} from '@angular/core';
- import {Http,Response} from '@angular/http';
- import 'rxjs/add/operator/toPromise';
- import 'rxjs/add/operator/catch';
- import 'rxjs/add/operator/debounceTime';
- import 'rxjs/add/operator/distinctUntilChanged';
- import 'rxjs/add/operator/map';
- import 'rxjs/add/operator/switchMap';
- @Component({
- selector: '.main',
- animations: [
- trigger(
- 'openClosePanel',
- [
- state('close, void', style({opacity:'0.2',top:'90%'})),
- state('open', style({opacity:'1',top:'40%'})),
- transition(
- 'close <=> open', [animate(500)])
- ]),
- trigger(
- 'openCloseHero',
- [
- state('close, void', style({opacity:'0',top:'-100%'})),
- state('open', style({opacity:'1',top:'10%'})),
- transition(
- 'close <=> open', [animate(500)]),
- transition(
- 'void => open', [animate(500)])
- ])
- ],
- templateUrl: '/selectHero.html'
- })
- export class AppComponent implements AfterViewInit,OnInit {
- styleExp = 'url("/images/main.jpg")';
- leftPlayImg1 = '/images/angularjs.png';
- leftPlayImg2 = '/images/expressjs.jpg';
- leftPlayImg3 = '/images/bootstrap.jpg';
- leftPlayImg4 = '/images/nodejs.png';
- leftPlayImg5 = '/images/npm.jpg';
- rightPlayImg1 = '/images/spring.jpg';
- rightPlayImg2 = '/images/struts2.jpg';
- rightPlayImg3 = '/images/typescript.jpg';
- rightPlayImg4 = '/images/tomcat.jpg';
- rightPlayImg5 = '/images/java.png';
- heroTypeCList = ["所有","战士","坦克","刺客","法师","射手","辅助"];
- heroTypeCCur = "所有";
- showListTypeCur = "LB";
- // loading
- loadFinished = false;
- loadingText = 'Hellow World! 你好!';
- // 获取dom元素 start
- // 英雄大头像圈
- @ViewChild('selHeroDiv') selHeroDiv: ElementRef;
- @ViewChild('selHeroDivOut') selHeroDivOut: ElementRef;
- @ViewChild('selHeroContain') selHeroContain: ElementRef;
- // 英雄列表面板
- @ViewChild('heroList') heroList: ElementRef;
- @ViewChild('hListMain') hListMain: ElementRef;
- @ViewChild('pullDown') pullDown: ElementRef;
- @ViewChild('pullUp') pullUp: ElementRef;
- // 英雄列表 图阵 切换
- @ViewChild('hListStyle1') hListStyle1: ElementRef;
- @ViewChild('hListStyle2') hListStyle2: ElementRef;
- // 抓取LOL服务器数据
- @ViewChild('getHeroList') getHeroListDom: ElementRef;
- // 显示英雄详细信息
- @ViewChild('hero') hero: ElementRef;
- // 英雄过滤名称
- @ViewChild('heroFilterName') heroFilterName: ElementRef;
- // 获取dom元素 end
- constructor(private renderer: Renderer,private http: Http) {
- // 初始:英雄列表隐藏
- this.statePanelExpression = 'close';
- // 初始:英雄详细隐藏
- this.stateHeroExpression = 'close';
- }
- ngAfterViewInit() {
- // 初期设置大头像位置 start
- var selHeroDivHW = this.selHeroDivOut.nativeElement.clientWidth;
- var selHeroContainHeight = this.selHeroContain.nativeElement.clientHeight;
- var selHeroContainWidth = this.selHeroContain.nativeElement.clientWidth;
- var selHeroContainLeft = this.selHeroContain.nativeElement.offsetLeft;
- var selHeroContainTop = this.selHeroContain.nativeElement.offsetTop;
- this.renderer.setElementStyle(this.selHeroDiv.nativeElement, 'width', selHeroDivHW+'px');
- this.renderer.setElementStyle(this.selHeroDiv.nativeElement, 'height', selHeroDivHW+'px');
- this.renderer.setElementStyle(this.selHeroDiv.nativeElement, 'left', selHeroContainLeft+(selHeroContainWidth-selHeroDivHW)*0.5 +'px');
- this.renderer.setElementStyle(this.selHeroDiv.nativeElement, 'top', selHeroContainTop+(selHeroContainHeight-selHeroDivHW)*0.5 +'px');
- this.renderer.setElementStyle(this.selHeroDiv.nativeElement, 'display', 'block');
- // 初期设置大头像位置 end
- }
- // 英雄列表面板显示隐藏控制 start
- statePanelExpression: string;
- showHeroListPanel() {
- this.renderer.setElementStyle(this.pullDown.nativeElement, 'display', 'none');
- this.statePanelExpression = 'open';
- this.renderer.setElementStyle(this.pullUp.nativeElement, 'display', 'block');
- this.renderer.setElementStyle(this.heroList.nativeElement, 'background', 'black');
- this.renderer.setElementStyle(this.hListMain.nativeElement, 'display', 'block');
- }
- hideHeroListPanel() {
- this.renderer.setElementStyle(this.pullUp.nativeElement, 'display', 'none');
- this.statePanelExpression = 'close';
- this.renderer.setElementStyle(this.pullDown.nativeElement, 'display', 'block');
- this.renderer.setElementStyle(this.heroList.nativeElement, 'background', 'gray');
- this.renderer.setElementStyle(this.hListMain.nativeElement, 'display', 'none');
- }
- showHideHeroListPanel(){
- if(this.statePanelExpression == 'close'){
- this.showHeroListPanel();
- }else{
- this.hideHeroListPanel();
- }
- }
- // 英雄列表面板显示隐藏控制 end
- // 英雄列表 图阵 切换 start
- heroListLB(){
- this.renderer.setElementStyle(this.hListStyle2.nativeElement, 'display', 'none');
- this.renderer.setElementStyle(this.hListStyle1.nativeElement, 'display', 'block');
- this.showListTypeCur = "LB";
- }
- heroListTZ(){
- this.renderer.setElementStyle(this.hListStyle1.nativeElement, 'display', 'none');
- this.renderer.setElementStyle(this.hListStyle2.nativeElement, 'display', 'block');
- this.showListTypeCur = "TZ";
- }
- // 英雄列表 图阵 切换 end
- // 抓取LOL服务器数据
- doGetHeroList(){
- this.renderer.setElementStyle(this.getHeroListDom.nativeElement, 'display', 'none');
- this.http.get('/getHeroList').toPromise().
- then(res =>
- {
- alert(res.text());
- this.renderer.setElementStyle(this.getHeroListDom.nativeElement, 'display', 'block');
- this.ngAfterViewInit();
- this.ngOnInit();
- }).catch((e)=>console.log(e));
- }
- // 显示英雄详细信息 start
- stateHeroExpression: string;
- curHeroDataId = '';
- heroShowDetail:any = {};
- heroShowDetailPassive:any = {};
- heroShowDetailPassiveImg = '';
- heroShowDetailSkins : Array<any> = [];
- heroShowDetailSpells1 :any = {};
- heroShowDetailSpells2 :any = {};
- heroShowDetailSpells3 :any = {};
- heroShowDetailSpells4 :any = {};
- heroShowDetailAllytips : Array<any> = [];
- heroShowDetailEnemytips : Array<any> = [];
- showHeroDetail(heroData:any){
- // 获取英雄详细数据
- this.curHeroDataId = heroData.id;
- this.http.get('/' + this.curVer + '/'+ heroData.id +'.json').toPromise()
- .then((res:Response)=>{
- if(JSON.parse(res.text()).data.id == this.curHeroDataId){
- this.heroShowDetail = JSON.parse(res.text()).data;
- this.heroShowDetailSkins = JSON.parse(res.text()).data.skins;
- this.heroShowDetail.tags = this.heroTypeEC2C(this.heroShowDetail.tags);
- this.heroShowDetailPassive = JSON.parse(res.text()).data.passive;
- this.heroShowDetailPassiveImg = JSON.parse(res.text()).data.passive.image;
- this.heroShowDetailSpells1 = JSON.parse(res.text()).data.spells[0];
- this.heroShowDetailSpells2 = JSON.parse(res.text()).data.spells[1];
- this.heroShowDetailSpells3 = JSON.parse(res.text()).data.spells[2];
- this.heroShowDetailSpells4 = JSON.parse(res.text()).data.spells[3];
- this.heroShowDetailSpells1.image = JSON.parse(res.text()).data.spells[0].image.full;
- this.heroShowDetailSpells2.image = JSON.parse(res.text()).data.spells[1].image.full;
- this.heroShowDetailSpells3.image = JSON.parse(res.text()).data.spells[2].image.full;
- this.heroShowDetailSpells4.image = JSON.parse(res.text()).data.spells[3].image.full;
- this.heroShowDetailAllytips = JSON.parse(res.text()).data.allytips;
- this.heroShowDetailEnemytips = JSON.parse(res.text()).data.enemytips;
- }
- }).catch(this.handleError);
- this.stateHeroExpression = 'open';
- }
- hideHeroDetail() {
- this.stateHeroExpression = 'close';
- }
- // 显示英雄详细信息 end
- // 英雄列表所有版本号
- heroVers = JSON.parse('{}');
- heroDataList : Array<any> = [];
- bakHeroDataList : Array<any> = [];
- curVer = '';
- ngOnInit(){
- // 取得英雄列表所有版本号
- // console.log('client get hero version');
- this.loadingText = '开始取得英雄列表所有版本号';
- this.http.get('/getHeroVers').toPromise()
- .then((res:Response)=>{
- this.heroVers = this.extractVersData(res);
- if(!this.heroVers && !this.heroVers.vers){
- this.loadingText = '服务器尚未抓取英雄列表,请点击右上角文字抓取数据。';
- return;
- }
- this.curVer = (this.heroVers && this.heroVers.vers &&this.heroVers.vers.length>0)?this.heroVers.vers[0]:'';
- if(this.curVer!=''){
- // 获取英雄列表json
- this.loadingText = '开始取得英雄列表';
- this.http.get('/' + this.curVer + '/herolist.json').toPromise()
- .then((res:Response)=>{
- if(JSON.parse(res.text()).version == this.curVer){
- this.heroDataList = [];
- for (var key in JSON.parse(res.text()).keys) {
- var heroIdTmp = JSON.parse(res.text()).keys[key];
- this.heroDataList.push(
- JSON.parse(res.text()).data[heroIdTmp]
- );
- this.bakHeroDataList.push(
- JSON.parse(res.text()).data[heroIdTmp]
- );
- }
- for (var i = this.heroDataList.length - 1; i >= 0; i--) {
- this.heroDataList[i].tags = this.heroTypeEC2C(this.heroDataList[i].tags);
- this.bakHeroDataList[i].tags = this.heroTypeEC2C(this.bakHeroDataList[i].tags);
- }
- this.heroDataTypeList = this.heroDataList;
- this.loadingText = '随机生成对战英雄';
- this.genFight();
- this.loadingText = '加载完成';
- this.loadFinished = true;
- }
- }).catch(this.handleError);
- }else{
- this.loadingText = '服务器尚未抓取英雄列表,请点击右上角文字抓取数据。';
- }
- }).catch(this.handleError);
- }
- genFight(){
- // 随机生成对战英雄
- var max = this.heroDataList.length;
- var randomI = Math.floor(Math.random()*max);
- this.leftPlayImg1 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
- var myHero = this.heroDataList[randomI];
- randomI = Math.floor(Math.random()*max);
- this.leftPlayImg2 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
- randomI = Math.floor(Math.random()*max);
- this.leftPlayImg3 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
- randomI = Math.floor(Math.random()*max);
- this.leftPlayImg4 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
- randomI = Math.floor(Math.random()*max);
- this.leftPlayImg5 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
- randomI = Math.floor(Math.random()*max);
- this.rightPlayImg1 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
- randomI = Math.floor(Math.random()*max);
- this.rightPlayImg2 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
- randomI = Math.floor(Math.random()*max);
- this.rightPlayImg3 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
- randomI = Math.floor(Math.random()*max);
- this.rightPlayImg4 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
- randomI = Math.floor(Math.random()*max);
- this.rightPlayImg5 = '/'+this.curVer+'/imgs/'+this.heroDataList[randomI].id+'.png';
- this.curHeroBigDataId = myHero.id;
- this.http.get('/' + this.curVer + '/'+ myHero.id +'.json').toPromise()
- .then((res:Response)=>{
- if(JSON.parse(res.text()).data.id == this.curHeroBigDataId){
- var max = JSON.parse(res.text()).data.skins.length;
- var randomI = Math.floor(Math.random()*max);
- this.styleExp = 'url("/'+this.curVer+'/skin/'
- +JSON.parse(res.text()).data.skins[randomI].id
- +'.jpg")';
- }
- }).catch(this.handleError);
- }
- // 处理英雄列表所有版本号
- private extractVersData(res: Response) {
- let body = JSON.parse(res.text());
- if(body && body.vers){
- body.vers.sort((a : any,b : any)=>b>a); // 简单排序,需要加工
- }
- return body || { };
- }
- private handleError (error: Response | any) {
- console.error(error);
- return { };
- }
- private heroTypeEC2C(ht:Array<string>): Array<string>{
- let result : Array<string> = [];
- for (var i = ht.length - 1; i >= 0; i--) {
- result.push(ht[i].replace('Mage','法师')
- .replace('Fighter','战士')
- .replace('Tank','坦克')
- .replace('Assassin','刺客')
- .replace('Marksman','射手')
- .replace('Support','辅助'));
- }
- return result;
- }
- removeTag(str:string):string{
- if(str)
- return str.replace(/<.*?>/ig,"");
- return '';
- }
- curHeroBigDataId = '';
- showBigPic(heroData:any){
- // 修改大图像
- this.leftPlayImg1 = '/'+this.curVer+'/imgs/'+heroData.id+'.png';
- this.curHeroBigDataId = heroData.id;
- this.http.get('/' + this.curVer + '/'+ heroData.id +'.json').toPromise()
- .then((res:Response)=>{
- if(JSON.parse(res.text()).data.id == this.curHeroBigDataId){
- var max = JSON.parse(res.text()).data.skins.length;
- var randomI = Math.floor(Math.random()*max);
- this.styleExp = 'url("/'+this.curVer+'/skin/'
- +JSON.parse(res.text()).data.skins[randomI].id
- +'.jpg")';
- }
- }).catch(this.handleError);
- }
- heroDataTypeList : Array<any> = [];
- filterType(type:string):void{
- // 选择英雄类型
- this.heroTypeCCur = type;
- this.heroDataList = this.bakHeroDataList.filter(
- (hero:any)=>this.heroTypeCCur =='所有' || hero.tags.contains(this.heroTypeCCur));
- this.heroDataTypeList = this.heroDataList;
- }
- filterTypeFun(hero:any){
- return hero.tags.contains(this.heroTypeCCur);
- }
- searchHeroByName(value: string){
- // 过滤英雄名称
- this.heroDataList = this.heroDataTypeList.filter(
- (hero:any)=>value ==''
- || hero.id.toLowerCase().indexOf(value.toLowerCase())>=0
- || hero.name.toLowerCase().indexOf(value.toLowerCase())>=0
- || hero.title.toLowerCase().indexOf(value.toLowerCase())>=0);
- }
- tempVer = '';
- getNewVersion(ver: string){
- // 重新获取英雄版本
- this.tempVer = ver;
- if(this.tempVer!='')
- // 获取英雄列表json
- this.http.get('/' + this.tempVer + '/herolist.json').toPromise()
- .then((res:Response)=>{
- if(JSON.parse(res.text()).version == this.tempVer){
- this.heroDataList = [];
- for (var key in JSON.parse(res.text()).keys) {
- var heroIdTmp = JSON.parse(res.text()).keys[key];
- this.heroDataList.push(
- JSON.parse(res.text()).data[heroIdTmp]
- );
- this.bakHeroDataList.push(
- JSON.parse(res.text()).data[heroIdTmp]
- );
- }
- for (var i = this.heroDataList.length - 1; i >= 0; i--) {
- this.heroDataList[i].tags = this.heroTypeEC2C(this.heroDataList[i].tags);
- this.bakHeroDataList[i].tags = this.heroTypeEC2C(this.bakHeroDataList[i].tags);
- }
- this.heroDataTypeList = this.heroDataList;
- this.genFight();
- this.curVer = ver;
- this.heroTypeCCur = '所有';
- this.heroFilterName.nativeElement.value = '';
- }
- }).catch((error: Response | any)=>{
- alert('错误:找不到改版本信息');
- return {};
- });
- }
- }
-----
中间效果图如下:
html模板制作:
抓取数据:
数据:
用angularjs2 绑定数据后:
首页:
列表:
详细:
检索:
没数据时:
转载请标明出处:cnblogs.com/wangxinsheng
@望星辰
全部源码地址:
http://download.csdn.net/user/wangxsh42
http://download.csdn.net/detail/wangxsh42/9737390
[nodejs,expressjs,angularjs2] LOL英雄列表数据抓取及查询显示应用的更多相关文章
- Android MaoZhuaWeiBo 好友动态信息列表数据抓取 -3
前面2篇把大致的开发说的几乎相同了,接下来说说粉丝动态消息列表或时间线数据的抓取与解析显示,我将他所有写在了一个 类里.并以封装类对象的形式存储数据.以下看看基本的服务代码: 粉丝动态消息列表数据抓取 ...
- [原创.数据可视化系列之十二]使用 nodejs通过async await建立同步数据抓取
做数据分析和可视化工作,最重要的一点就是数据抓取工作,之前使用Java和python都做过简单的数据抓取,感觉用的很不顺手. 后来用nodejs发现非常不错,通过js就可以进行数据抓取工作,类似jqu ...
- Phantomjs+Nodejs+Mysql数据抓取(2.抓取图片)
概要 这篇博客是在上一篇博客Phantomjs+Nodejs+Mysql数据抓取(1.抓取数据) http://blog.csdn.net/jokerkon/article/details/50868 ...
- Phantomjs+Nodejs+Mysql数据抓取(1.数据抓取)
概要: 这篇博文主要讲一下如何使用Phantomjs进行数据抓取,这里面抓的网站是太平洋电脑网估价的内容.主要是对电脑笔记本以及他们的属性进行抓取,然后在使用nodejs进行下载图片和插入数据库操作. ...
- Python数据抓取_BeautifulSoup模块的使用
在数据抓取的过程中,我们往往都需要对数据进行处理 本篇文章我们主要来介绍python的HTML和XML的分析库 BeautifulSoup 的官方文档网站如下 https://www.crummy.c ...
- 网页数据抓取工具,webscraper 最简单的数据抓取教程,人人都用得上
Web Scraper 是一款免费的,适用于普通用户(不需要专业 IT 技术的)的爬虫工具,可以方便的通过鼠标和简单配置获取你所想要数据.例如知乎回答列表.微博热门.微博评论.淘宝.天猫.亚马逊等电商 ...
- 大数据抓取采集框架(摘抄至http://blog.jobbole.com/46673/)
摘抄至http://blog.jobbole.com/46673/ 随着BIG DATA大数据概念逐渐升温,如何搭建一个能够采集海量数据的架构体系摆在大家眼前.如何能够做到所见即所得的无阻拦式采集.如 ...
- python实现一个栏目的分页抓取列表页抓取
python实现一个栏目的分页抓取列表页抓取 #!/usr/bin/env python # coding=utf-8 import requests from bs4 import Beautifu ...
- Python爬虫工程师必学——App数据抓取实战 ✌✌
Python爬虫工程师必学——App数据抓取实战 (一个人学习或许会很枯燥,但是寻找更多志同道合的朋友一起,学习将会变得更加有意义✌✌) 爬虫分为几大方向,WEB网页数据抓取.APP数据抓取.软件系统 ...
随机推荐
- Python开发环境Wing IDE使用教程:部分调试功能介绍
下面是用户应该了解的Wing IDE的其它一些调试功能: Main Debug File—用户可以指定项目中的一个文件作为调试的主入口点.当完成这个设置之后,调试总是从这个文件开始,除非用户使用Deb ...
- JQUERY 插件开发——MENU(导航菜单)
JQUERY 插件开发——MENU(导航菜单) 故事背景:由于最近太忙了,已经很久没有写jquery插件开发系列了.但是凭着自己对这方面的爱好,我还是抽了一些时间来过一下插件瘾的.今天的主题是导航菜单 ...
- RPC服务的发布订阅实现Thrift
Thrift 个人实战--RPC服务的发布订阅实现(基于Zookeeper服务) 前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的 ...
- (转)C++重写、重载和重定义的区别
C++ 重写重载重定义区别 (源自:http://blog.163.com/clevertanglei900@126/blog/static/111352259201102441934870/) 1 ...
- 企业架构研究总结(28)——TOGAF架构开发方法(ADM)之需求管理阶段
1.11 需求管理(Requirements Management) 企业架构开发方法各阶段——需求管理 1.11.1 目标 本阶段的目标是定义一个过程,使企业架构的需求可以被识别.存储并与其他架构开 ...
- DevExpress 学习使用之 Skin
新建了一个XtraForm,设置属性里的皮肤属性却不能实现,群里朋友发过来一个简单的换肤项目 1. 先觉条件似乎是窗体应该继承“public partial class XtraForm1 : Dev ...
- 搭建一个完整的Java开发环境
搭建一个完整的Java开发环境 作为一个Java程序员,配置一个java开发环境是必备的技能,今天给广大菜鸟初学者补上一课.环境的配置,大概就分三个1,JDK 2,Tomcat(或者其他的)3,ecl ...
- c:forEach 实现换行
Map<String,String> map = new TreeMap<String,String>(); map.put("key1", "v ...
- ngx-push-stream模块源码学习(五)——内存清理
1.定时器 采用nginx自身的定时器管理机制,具体细节待学习过nginx源码后加以补充 2.channel的生成周期 (0).初始(诞生) 发布.订阅均有可能产生ch ...
- SVN Access to '/svn/Test/!svn/me' forbidden,不能更新解决办法
从之前的电脑将Repositorise复制到现在用的PC,出现可以checkout但是不能update的问题.在网上找到以下解决方法,均未能解决. 1.确认URL跟实际一致: 2.确认用户名密码正确: ...