接下來回到首頁,想一想現有功能的缺陷,是的,如今首頁只能顯示當前月的todos,看動漫中的狀況,頁面是有一個雙重的滑動功能,在單月的狀況下,滑動更新每月的todos,而後到底以後,再去更新下一個月份,接下來要針對這個功能對首頁內的todos各模塊進行改造css
對於Panel組件來講,修改一下class便可:vue
\components\DiaryPanel.vuejava
.itemlist{ position:relative; padding: 15px; overflow-y: scroll; //縱軸顯示滾動條 height: 100%; z-index: 1; }
而後修改list組件,以前的代碼是直接進行item的循環,這裏要在外邊包裹一層容器:git
\components\DiaryPanel.vuegithub
<div class="diarypanel"> <mu-paper class="diaryitem" :zDepth="2" v-for="(item) in todos" > ... </mu-paper> </div>
首先一樣是修改css:vuex
.diarypanel{ overflow-y: scroll; }
這時候運行起來,你會發現,縱向滾動條依然沒法顯示,通過排查,緣由爲這個容器的高度不固定。沒辦法,在首頁給這個容器加上一個樣式:vue-cli
\views\Index.vueapi
<div id="contentPanel"> <transition name="custom-classes-transition" enter-active-class="animated bounceInLeft" leave-active-class="animated fadeOut" :duration="{ enter: 700, leave: 200 }"> <component v-bind:is="currentView"> </component> </transition> </div>
到了contentPanel的樣式:瀏覽器
#contentPanel{ overflow-y: scroll; }
能夠看到,依然不能夠。服務器
在繼續修改樣式以前,咱們先對數據進行一下修改,修改成若是發現數據不能撐滿一屏,那麼繼續查詢下一個月,下面一步一步的完成這個改變,客戶端開始,首先將讀取的部分抽象獨立出來:
setIndexData:function(data){ this.$http.post("/api/index",data,{headers:{"token":this.token}}).then(res=>{ ... },res=>{ ... }) },
以前的refresh進行改造:
refresh:function(data){ this.setIndexData(data); },
而建立頁面的時候首先會調用一次Irefresh,並付給當前的年份和月份:
created(){ var month=(new Date()).getMonth(); var year=(new Date()).getFullYear(); this.refresh({month:month,year:year}) },
新增一個記錄頁面總記錄數的變量,就叫allCount,每次回調以後更新此值:
if(!(result== undefined ||result=="")){ ... this.allCount+=result.items[0].todos.length; ... }
同時這裏作一個是否充滿屏幕的判斷,採用最簡單粗暴的方法,小於10條即認爲他沒有將屏幕充滿,即新增一條判斷:
this.allCount+=result.items[0].todos.length; if(this.allCount<10){ this.refresh({year:data.year,month:--data.month}) }
同時,在vuex部分還進行一下削繁就簡,將疊加服務端返回todos的部分包裝起來:
addIndexData(state,indexTodos) { if(state.indexTodos[0].month==-1){ state.indexTodos=[indexTodos]; } else{ var temp=state.indexTodos temp.push(indexTodos); state.indexTodos=temp; } },
同時month的默認值給-1,而後setIndexData就能夠光榮的退休了,直接刪除便可。
下面運行看一下效果:
看上去彷佛很是不錯,可是,用手劃一下會怎麼樣呢?
能夠看到,一月份以後並無變爲上一年的12月份,看來以前的技術債務到了償還的時候了。首先仍是修改服務端的Controller的增長year的參數。
Integer year=Integer.parseInt(map.get("year").toString());
而後修改服務層參數,這裏實際上不須要只有一個月份參數的時間區間,因而加上年份:
public List<Todo> getTodoByDefaultGroup(int userId,int year,int month) { TodoGroup todoGroup=todoGroupRepository.findByIsDefaultAndUserId(1,userId); DateBetween between=getDate(year,month); List<Todo> todos= todoRepository.getByGroupIdAndCreateTimeBetween(todoGroup.getId(),between.getFirstDate(),between.getEndDate()); return todos; }
getDate的修改地點極少,只須要給first和end增長一行代碼就好了:
private DateBetween getDate(int year, int month ){ DateBetween between=new DateBetween(); Calendar firstCalender = Calendar.getInstance(); // 獲取前年月的第一天 firstCalender.set(Calendar.YEAR,year); ... between.setFirstDate(firstCalender.getTime()); // 獲取前年月的最後一天 Calendar endCalender = Calendar.getInstance(); endCalender.set(Calendar.YEAR,year); ... return between; }
而後對controller調用的部分進行修改。而且返回年份:
...... List<Todo> todos = todoService.getTodoByDefaultGroup(Integer.parseInt(userId),year,month); Map<String, Object> data = new HashMap<String, Object>(); data.put("month", month+1); //java的月份從0開始 data.put("todos", todos); data.put("year", year); data.put("default", 1); items.add(data); ......
ok 服務端改造完成
客戶端因爲設計的缺陷,組件化不夠完全,首頁和panel頁均訪問服務器獲取todos,這就要求他們兩個均能讀取年份和月份的信息並能分別計算,爲了方便,從vuex入手(暫時依然不考慮使用getter),首先修改模型,增長year屬性:
indexTodos:[ { month:-1, year:0, default:1, todos } ],
而後修改index.vue,新增考慮年份的計算方法:
getBeforeMonth(year,month){ if(month>0){ return {year:year,month:--month} }else{ return{ year:--year, month:11 } } },
調用的地方修改成:
if(this.allCount<10){ this.refresh(this.getBeforeMonth(data.year,data.month)) }
先採用最反模式的方法,在DiaryPanel.vue內一樣更新一個相似的方法,同時對查詢服務器方法的參數作適當的修改(由月份數字改成年月組成的對象):
getBeforeMonth(year,month){ if(month>0){ return {year:year,month:--month} }else{ return{ year:--year, month:11 } } }, upTodos(data){ console.log(data.year); console.log(data.month); ... }
下面再次用土土的方法測試一下:
這時候看一下瀏覽器的輸出:
啊哦,一直在往下查詢,都查到了1987年,一會兒查詢了30年。這是一個小bug,最終要在頁低輸出一個已是最後一條,爲了方便操做,將首條記錄的年月時間保存在客戶端,首先修改一下vuex的模型:
firstYear:0, firstMonth:0
設置值的方法略。
接下來服務端查詢首條記錄時間,以年月方式返回:
@RequestMapping(value = "/api/mindate",method = RequestMethod.POST) public Object getMinDate(HttpServletRequest request,@RequestBody Map map){ Integer userId= Integer.parseInt(request.getAttribute("tokenId").toString()); Date firstDate=todoService.getFirstDateByGroupId(userId); Map<String, Object> data = new HashMap<String, Object>(); Calendar calendar=Calendar.getInstance(); calendar.setTime(firstDate); data.put("year",calendar.get(Calendar.YEAR)); data.put("month",calendar.get(Calendar.MONTH)); return result(data); }
服務層:
public Date getFirstDateByGroupId(int userId) { TodoGroup todoGroup=todoGroupRepository.findByIsDefaultAndUserId(1,userId); Todo todo=todoRepository.getFirstByGroupIdOrderByCreateTime(todoGroup.getId()); return todo.getCreateTime(); }
orm略
而後在進入首頁的時候調用,並保存:
refresh:function(data){ this.$http.post("/api/mindate",{},{headers:{"token":this.token}}).then(res=>{ console.log(res); if(res.data.msg!=""){ this.$router.push({name:"Login"}) } var result=res.data.data; if(!(result== undefined ||result=="")){ console.log(result); this.$store.commit('setFirstYear',result.year); this.$store.commit('setFirstMonth',result.month); } },res=>{ //查詢服務器失敗 this.$router.push({name:"Login"}) }) this.setIndexData(data); },
而判斷方式,則採用最簡單粗暴的,只判斷一下年份:
if(data.year>=this.firstYear){ this.upTodos(this.getBeforeMonth(data.year,data.month)) }else{ this.loading=false; }
同時,loadMore方法也須要作一下判斷這裏就要年份和月份一樣判斷了:
loadMore () { //賦值 var year=this.indexTodos[this.indexTodos.length-1].year var month=this.indexTodos[this.indexTodos.length-1].month-1 //上一個月 if(year>=this.firstYear&&month>this.firstMonth){ this.loading = true this.upTodos(this.getBeforeMonth(year,month)); } },
再次運行,這個bug消失了。
償還了部分技術債務,而且修改了部分bug,這一章也暫時告一段落。
客戶端代碼:
github
服務端代碼:
github