zoukankan      html  css  js  c++  java
  • 如果你想开发一个应用(1-23)

    image.png

    首页功能

    接下来回到首页,想想现有功能的缺陷,是的,现在首页只能显示当前月的todos,看动漫中的情况,页面是有一个双重的滑动功能,在单月的情况下,滑动更新每个月的todos,然后到底之后,再去更新下一个月份,接下来要针对这个功能对首页内的todos各模块进行改造

    布局改造

    对于Panel组件来说,修改一下class即可:

    componentsDiaryPanel.vue

    .itemlist{
    	position:relative;
    	padding: 15px;
    	overflow-y: scroll;  //纵轴显示滚动条
    	height: 100%;
    	z-index: 1;			 
    }
    

    然后修改list组件,之前的代码是直接进行item的循环,这里要在外边包裹一层容器:

    componentsDiaryPanel.vue

    <div class="diarypanel">
    	<mu-paper class="diaryitem" :zDepth="2" v-for="(item) in todos" >
    		...		
    	</mu-paper>
    </div>
    

    首先同样是修改css:

    .diarypanel{
    	overflow-y: scroll;
    }
    

    这时候运行起来,你会发现,纵向滚动条依然无法显示,经过排查,原因为这个容器的高度不固定。没办法,在首页给这个容器加上一个样式:

    viewsIndex.vue

    <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就可以光荣的退休了,直接删除即可。

    下面运行看一下效果:

    image

    看上去似乎非常不错,但是,用手划一下会怎么样呢?

    image

    偿还服务端债务##

    可以看到,一月份之后并没有变为上一年的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);
    	...
    }
    

    下面再次用土土的方法测试一下:

    image

    修改一个bug

    这时候看一下浏览器的输出:

    image

    啊哦,一直在往下查询,都查到了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

  • 相关阅读:
    Python实用笔记 (24)面向对象高级编程——使用@property
    Python实用笔记 (23)面向对象高级编程——使用__slots__
    Python实用笔记 (22)面向对象编程——实例属性和类属性
    Python实用笔记 (21)面向对象编程——获取对象信息
    Python实用笔记 (20)面向对象编程——继承和多态
    Python实用笔记 (19)面向对象编程——访问限制
    Python实用笔记 (18)面向对象编程——类和实例
    Python实用笔记 (17)模块
    Python实用笔记 (16)函数式编程——偏函数
    Python实用笔记 (15)函数式编程——装饰器
  • 原文地址:https://www.cnblogs.com/jiangchao226/p/8509279.html
Copyright © 2011-2022 走看看