若是你想開發一個應用(1-23)

image.png

首頁功能

接下來回到首頁,想一想現有功能的缺陷,是的,如今首頁只能顯示當前月的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就能夠光榮的退休了,直接刪除便可。

下面運行看一下效果:

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

相關文章
相關標籤/搜索