之前的專案在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物件。
和狗子一起成為更好的人。