接下来回到首页,想一想现有功能的缺陷,是的,如今首页只能显示当前月的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