之前的项目在charts这一块没有做好,今天来学习大佬的代码。
我跑了一下,大佬的数据库已经删光了,就是说后台没有数据的,只能光看代码了,不知道后天传来的json格式是怎么样的, 但是我之前写过,echart这个插件也是用过的,他需要什么样的data我也大概清楚。
先看一下页面效果吧:
东哥这个页面跟我之前的设计是差不多的,当type变成pie时,会有多一个Crawler的选项进行选择。
HTML:
在project这里绑定是searchForm里面的project ng-init把数据初始化为SSM2014.
ng-option里面加载在数据库里面度到的所有project(有获取所有project的api)。
时间搜索栏,跟我之前写的没什么区别:
这里是选择type,也是从后台获取type类型,我之前是写死的:
这是选择Crawler的时候,有分type来显示。我之前的设计思路是放在一起的:也就是有三个按钮,分别对应三个div,div里面包括了各项输入框啊,project,date,还有crawler。而东哥是直接利用ng-show来判断是否显示,相比我的来说更为简洁。
uib-typehead:根据输入的值来智能提示,提示的那些option全部在clazzname,而clazzname里面的元素全是从数据库拿的。
filter:拦截器。
limitTo:最多一次显示8条。
ng-blur:鼠标焦点离开的时候执行方法。
autocomplete:自动完成功能关闭。
require:必填。
重头戏:
三个图的排版,我之前被搞得很头痛,也是卡住我的一个很关键的点。我之前利用的方法是:Echart是会把图生成以后,放在一个你制定ID的div中,当每次用户切换type的时候(点击按钮),type一改变,就会执行http方法,就会在getchart这个方法中,把我想要的图替换到div中。
首先是三个div,利用ng-if,判断当前的type是什么,来控制显示。具体的逻辑放到后面讲js的时候说。
AG部分:
没什么好说,注入依赖。
search按钮执行的方法:
拼接请求的url: 获取各个输入框的值,如果是line和pie就再拼一个日期,哇,感觉这里的思维就跟我很不同,如果是我,我就会在写一个function,而其实只要简单写一个判断就行了,果然是思维不同,代码的复用性和模块化还没有能好好运用。
把传回来的数据全部放入scope中,因为看不到后台,也不知道传回来的具体格式是怎么样的,但应该就是echart里面可以直接拿来用的格式。
reset按钮执行的方法。
date输入框的一些配置。
获取后台的数据显示到前台的具体实现方法:
已经有写好的api可以返回所有project,把data中的数据传到scope里面的allproject里面然后利用ng-options显示出来就行。
而Crawler的模糊查询就复杂一丢丢,也是利用api,而api所需要拼接的url是这样子的:
他需要你选择的project的名字,很简单,利用了双向数据绑定嘛,那么怎么动态显示呢,就是当你选择了project,crawler就会及时更新:
利用ng-change,顾名思义就是当里面的值变化时,就会执行initAllCrawler()这个来替换。
我之前提到的ng-blur,就是失去鼠标焦点就会执行的方法,因为这是在Crawler输入框内设置的方法,其实他在这里执行的是一个验证,毕竟是个输入框,虽然有提示信息,但是user不一定会去根据提示的信息输入正确的crawler,如果输入错误的怎么办呢,所以这里就执行了一个方法来验证。
这里的$$scope.clazzName是在$$initAllCrawler的时候已经赋值了,里面是所有的Crawler。在输入框内,他已经绑定了数据(就是这个($scope.search.clazz),然后遍历所有的crawler看看是不是存在用户输入的值,如果存在,那么pass这个标识符就会被设置成true。不存在,就设置为空,传回来的所有的crawler的data。
这里实现的是分页,也是之前我不知道怎么搞得一个功能,我就很少搞过分页:
首先先设置好默认的参数:
currentPage:当前页 pageLimit:页数限制 itemPerPage:每一页显示的的item数。
clickLimit方法:
是改变每一页显示的数目的。
因为默认设置的是4,所以没有改变的话,直接return空。
这里有进行验证,如果为空,为undefined,isNaN是is not a number的缩写:返回一个boolean。
这个$scope.itemPerPage好像没什么用,在search方法里面并没有用到。。。
jumpToPage就是跳到选择的页数:
点击go的会执行,替换currentPage,再执行searchChart()。
这里用到的是ui-bootstrap,原来分页也可以用ui-bootstrap做。
这里有个不是明白的点:为什么要重新var 一个值进行判断,直接判断不行吗:
最后来看东哥分别写的三个指令:
}]).directive('barcrawler', function () {
return {
restrict:'E',
template:"<div style='width:100%; height: 600px;'></div>",
replace: true,
scope: {
chartData: '='
},
link: function (scope, element, attrs) {
var data = scope.chartData.crawlerSummary;
var option = {
title : {
text:"Crawler Summary"
},
tooltip : {
trigger: 'axis',
axisPointer : {
type : 'shadow'
}
},
legend: {
data:[]
},
calculable : true,
xAxis : [],
yAxis : [
{
type : 'value'
}
],
grid: {
left: 80,
right: 0
},
series : []
};
var series = data.series;
//legend and series setting
for(var type in series){
option.legend.data.push(type);
var seriesTmp = {
name:type,
type:'bar',
stack:'summary',
itemStyle : {
normal: {
label : {
show: true,
position: 'insideRight'
}
}
},
data:series[type]
};
option.series.push(seriesTmp);
}
//xAxis setting
option.xAxis.push({
type:'category',
axisLabel:{
interval:0,
textStyle:{
fontSize:12
}
},
data:data.xAxis
});
echarts.init(element[0]).setOption(option);
}
};
复制代码
用了“=”值传递,就是双向数据绑定了chartdata在这个directive里面独有的scope中。
看不到效果,也不知道东哥用的是那个chart图,但后面大致上,也都是把返回的json数据,拼接进option里面的data里面, 然后把option set进去,就可以显示了。
element指的是这个标签的dom对象。
和狗子一起成为更好的人。