세모튜브

小程序 앱만들기 - 7-2 : list 및 page 구현하기 본문

미니프로그램-小程序/위챗-관광정보 앱

小程序 앱만들기 - 7-2 : list 및 page 구현하기

iDevKim 2020. 5. 22. 17:50

유튜브 강좌 : youtu.be/3atwE76ax3g

 

조건식을 만들어 서버에 요청하기

- 첫화면 onShow()에서  "통합검색"  "request" 처리하기

  onShow() {
    let needSearch = false;
    if(this.data.tabArray[0].categoryArray[0].length === 0 || this.data.tabArray[0].areaArray[0].length === 0) { //재확인
      this.initData();
      //배열 초기화 후 다시 한번 확인. 
      if(this.data.tabArray[0].categoryArray[0].length || this.data.tabArray[0].areaArray[0].length)
        needSearch = true;
      else
        return;
    }
    if(needSearch || !this.data.tabArray[this.data.TabCur].resArray.length)
      this.bindSearch();
  },
  
  
  
  
  
// search
//////////////////////////////////////////////////////
  bindSearch(type="reLoad") {
    //페이지 처리를 위해 전체갯수 파악 ==> "reLoad" 혹은 검색버튼 클릭시 : type.type==="tap"
    if(type==="reLoad" || type.type==="tap") {
      this.data.tabArray[this.data.TabCur].listYN = "N";
    }    
    
    this.hideModal();
    
    if(this.data.tabArray[this.data.TabCur].keyword) {
      if(this.data.tabArray[this.data.TabCur].keyword.length < 2) {
        util.showToast("검색어는 2글자이상\n\n 필요합니다.","none");
        return false;
      }
    }
    
    switch (this.data.TabCur) {
      case 0://searchKeyword : 통합검색 
        this.searchKeyword();
        break;
      case 1://searchFestival : 행사검색
        this.searchFestival();
        break;
      case 2://searchStay : 숙박검색
        this.searchStay();
        break;
      default: break;
    }
  },


  searchKeyword() {
    let that = this;
    let tab = that.data.tabArray[that.data.TabCur];
    let param = {
      contentTypeId: tab.contentArray[tab.contentIndex],
      cat1: tab.categoryArray[0][tab.categoryIndex[0]],
      cat2: tab.categoryArray[1][tab.categoryIndex[1]],
      cat3: tab.categoryArray[2][tab.categoryIndex[2]],
      areaCode: tab.areaArray[0][tab.areaIndex[0]],
      sigunguCode: tab.areaArray[1][tab.areaIndex[1]],
      keyword: tab.keyword,
      arrange: tab.arrangeArray[tab.arrangeIndex],
      numOfRows: tab.numOfRows,
      pageNo: tab.pageNo,
      listYN: tab.listYN,
    }
    //keyword가 있으면 SearchKeyword 없으면 AreaBasedList
    api.request(param.keyword != "" ? api.SearchKeyword : api.AreaBasedList, {
      contentTypeId: param.contentTypeId.code,
      cat1: param.cat1.code,
      cat2: param.cat2.code,
      cat3: param.cat3.code,
      areaCode: param.areaCode.code,
      sigunguCode: param.sigunguCode.code,
      keyword: param.keyword,
      arrange: param.arrange.code,
      numOfRows: param.numOfRows,
      pageNo: param.pageNo + 1,
      listYN: param.listYN,
    }).then(function (res) {
      // console.log("res : ", res)
      if (res.response.header.resultMsg === "OK") {
        let item = res.response.body.items.item;
        if (!Array.isArray(item)) item = [item];

        if( tab.listYN === "N" ) {
//처음(검색시작버튼)이거나 refresh이므로 pageTot계산후 첫 List를 다시 읽어드림.        
          if( item[0].totalCnt ) {
            that.setData({
              [`tabArray[${that.data.TabCur}].pageTot`]: Math.ceil(item[0].totalCnt/tab.numOfRows),
              [`tabArray[${that.data.TabCur}].listYN`]: "Y",//List
              [`tabArray[${that.data.TabCur}].resArray`]: [],//result 초기화.
              [`tabArray[${that.data.TabCur}].pageNo`]: 0,//현재페이지 초기화.
            })
			that.searchKeyword();//다시 읽어드림
          } else {
            util.showToast("NO 데이터","error");
          }
        } else {
//자료를 추가로 읽어드림 reLoad 상태        
          if(item != undefined) { 
            that.setData({
              [`tabArray[${that.data.TabCur}].resArray`]: tab.resArray.concat( item ),
              [`tabArray[${that.data.TabCur}].pageNo`]: tab.pageNo + 1,//페이지+1.
            })
          } else {  
            util.showToast("NO 데이터","error");
          }
        }
        util.hideLoading();
      } else { console.error("resultMsg != 'OK' : ", res.response.header.resultMsg) }
    })
    .catch(function (res) {
      util.hideLoading();
      console.error("catch : ", res)
    })
  },

레이아웃

<!-- 통합검색 scroll-view -->
<block wx:if="{{TabCur==0}}">
  <scroll-view wx:if="{{tabArray[TabCur].resArray.length}}" scroll-y="{{modalName==null}}" class="page {{modalName!=null?'show':''}}">
    <view class="cu-list menu-avatar">
      <view class="cu-item" wx:for="{{tabArray[TabCur].resArray}}" wx:key="index" bindtap="bindDetail" data-item="{{item}}">
        <view class="cu-avatar radius lg" style="background-image:url({{item.firstimage2}});">
          <text wx:if="{{!item.firstimage2}}" class="cuIcon-picfill lg text-gray"></text>
        </view>
        <view class="content">
          <view>
            <text class="text-cut">{{item.title}}</text>
          </view>
          <view class="text-gray text-sm flex">
            <text class="cuIcon-phone text-grey margin-right-xs"></text> {{item.tel}}
          </view>
        </view>
        <view class="action">
          <view class="text-grey text-xs">{{util.toDate(item.modifiedtime)}}</view>
          <view class="text-grey text-xs"><text class="cuIcon-attention margin-right-xs"></text>{{item.readcount}}</view>
        </view>
      </view>
    </view>
  </scroll-view>
  <view wx:else class="padding-top-xl text-center text-shadow text-grey">
    <text class="text-bold text-xxl">데이터가 없습니다.</text>
  </view>
</block>

 

실행화면

 

 

조건 넣어보기

타입 : 관광지

지역 : 부산, 시군구 전체

실행화면

 

 

페이지 처리하기

참고 자료 : https://developers.weixin.qq.com/miniprogram/en/dev/reference/api/Page.html 

 

먼저 json파일에 "enablePullDownRefresh": true 선언을 해주어야 한다.

 

search.json

{
  "usingComponents": {},
  "enablePullDownRefresh": true
}

 

페이지 처리하기 위해서는 기본적으로 <scroll-view>컴포넌트와 onPullDownRefresh(), onReachBottom() 함수를 사용한다.

onPullDownRefresh() : js에 구현 => 자료의 처음을 처리

 

onReachBottom() : js에 구현 => 자료의 마지막을 처리

<scroll-view> : wxml에 구현 => 자료 리스트 표현를 처리

 

소스코딩

//page 처리
/////////////////////////////////////////////////////////////////////////////////
  onPullDownRefresh: function(){
    wx.stopPullDownRefresh();
    if(this.data.tabArray[this.data.TabCur].resArray.length === 0) {
      return;
    }
    this.bindSearch();
  },
  onReachBottom() {
    if(this.data.tabArray[this.data.TabCur].resArray.length === 0) {
      return;
    }
    let tab = this.data.tabArray[this.data.TabCur];
    if (tab.pageTot > tab.pageNo) {
      this.bindSearch("loadPage");
    } else {
      wx.showToast({
        title: '자료의 끝입니다.',
        icon: 'none',
        duration: 2000
      });
    }
  },

 

실행화면

조건 - 화면 상단 좌측 페이지 확인

- 타입 : 음식점

- 검색어 : 돼지

 

reFresh : 화면을 끌어 내리면 onPullDownRefresh() 호출되며 동작한다.

reLoad : 화면을 끌어 올리면 onReachBottom() 호출되며 동작한다.

메이지의 마지막일때