세모튜브

小程序 앱만들기 - 8-2 : detail page 만들기 - 공통정보 본문

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

小程序 앱만들기 - 8-2 : detail page 만들기 - 공통정보

iDevKim 2020. 5. 25. 18:48

유튜브 강좌 : youtu.be/lZIDBWwUl2E

 

 

리스트에서 항목을 선택하면 세부정보를 보여주는 페이지를 구현해 보자

기본적으로 아래와 같이 처리하는것으로 하자.

별표아이콘 : 나의 즐겨찾기 on/off

공통정보 : detailCommon 오퍼레이션 이용

소개정보 : detailIntro 오퍼레이션 이용

추가이미지 : detailImage 오퍼레이션 이용

 

메뉴얼 참조

 

 

페이지 생성

"pages/search/detail/detail"

 

3가지 Tab처리

- 공통정보, 소개정보, 추가이미지

 

소스처리

// pages/search/detail/detail.js
const api = require("../../../utils/api.js");
const util = require("../../../utils/util.js");
const def = require("../../../utils/def.js");
const WxParse = require("../../../wxParse/wxParse.js");
const app = getApp()

class Tab {
  constructor(name) {
    this.name = name;
    this.reqState = "start";//"start","finish"
    this.resArray = [];
  }
}

Page({
  data: {
    StatusBar: app.globalData.StatusBar,
    CustomBar: app.globalData.CustomBar,
    TabCur: 0,

    tabArray: [
      new Tab("공통정보"),
      new Tab("소개정보"),
      new Tab("추가이미지")
    ],
  },
  
  onLoad: function (options) {
  },
  
  tabSelect(e) {
    this.setData({
      TabCur: e.currentTarget.dataset.id,
    })
  },
})

레이아웃

<!--pages/search/detail/detail.wxml-->
<wxs    src="../../../utils/script.wxs" module="script" />
<import src="../../../wxParse/wxParse.wxml" />

<cu-custom bgColor="bg-green" isBack="{{true}}">
  <view slot="backText">뒤로</view>
  <view slot="content">세부정보</view>
</cu-custom>

<!-- 상단 Tab -->
<view class="fixed flex bg-gray" style="top:{{CustomBar}}px;">
<!-- 즐겨찾기버튼 -->
  <view class="basis-1 flex align-center justify-center" bindtap="bindFavor" data-target="keyword">
    <view class="cu-avatar round bg-white text-xxl">
      <text class="cuIcon-{{tabArray[0].resArray[0].isFavor?'favorfill':'favor'}} text-red"></text>
    </view>
  </view>
<!-- tab   -->
  <view class="basis-9">
    <scroll-view scroll-x class="nav">
      <view class="flex text-center">
        <view class="cu-item flex-sub {{index==TabCur?'text-green cur':''}}" wx:for="{{tabArray}}" wx:key="index" bindtap="tabSelect" data-id="{{index}}">
          {{tabArray[index].name}}
        </view>
      </view>
    </scroll-view>
    <view class="cu-tag badge">{{tabArray[2].resArray != ''?tabArray[2].resArray.length:"없음"}}</view>
  </view>
</view>

<!-- 공통정보 view -->
<block wx:if="{{TabCur==0}}">
  결과 리스트 - 공통정보
</block>

<!-- 소개정보 view -->
<block wx:if="{{TabCur==1}}">
  결과 리스트 - 소개정보
</block>

<!-- 추가이미지 view -->
<block wx:if="{{TabCur==2}}">
  결과 리스트 - 추가이미지
</block>

스타일시트

/* pages/search/detail/detail.wxss */

@import "/wxParse/wxParse.wxss";

page {
	padding-top: 100rpx;
	background-color: white;
}

.fixed {
	position: fixed;
	width: 100%;
	top: 0;
	z-index: 1024;
}

.basis-1 {
	flex-basis: 10%;
}
.basis-9 {
	flex-basis: 90%;
}

.cu-tag.badge {
	border-radius: 200rpx;
	position: absolute;
	top: 10rpx;
	right: 30rpx;
	font-size: 20rpx;
	padding: 0rpx 10rpx;
	height: 28rpx;
	color: var(--white);
}

.noImage {
	width: 100%;
	height: 100%;
	font-size: 120rpx; 
	border: 1rpx solid rgba(0, 0, 0, 0.1);
}

실행결과

 

 

공통정보 오퍼레이션 처리하기

search.js와 detail.js 연결 데이터 처리하기

 

보내기

search.js에서 선택한 항목에 대한 contentid, contenttypeidwx.navigateTo이용해 detail.js를 호출할때 아래와 같이 데이터를 함께 보낸다.

 

search.wxml : 통합검색 리스트에서 항목선택시 bindtap="bindDetail" data-item="{{item}}"

<!-- 통합검색 scroll-view -->
...
...
<view class="cu-item" wx:for="{{tabArray[TabCur].resArray}}" wx:key="index" bindtap="bindDetail" data-item="{{item}}">

search.js : url: './detail/detail?contentid='+item.contentid+'&contenttypeid='+item.contenttypeid

//bind Detail
  bindDetail(e) {
    let item = e.currentTarget.dataset.item;
    wx.navigateTo({
      // url: './detail/detail?item='+item,
      url: './detail/detail?contentid='+item.contentid+'&contenttypeid='+item.contenttypeid,
    })
  }  

 

받기

search.js에서 보낸값을  detail.js에서 받기

 onLoad: function (options) {
   console.log("options : ", options);
 },

 

공통정보 Tab 처리하기

- 서버에 request보내기

 

소스처리

  onLoad: function (options) {
    console.log("options : ", options);
    this.detailCommon(options.contentid, options.contenttypeid);
  },
  
  
  
  //공통정보  
  detailCommon(contentId, contentTypeId) {
    let that = this;
    that.data.tabArray[0].reqState = "start";
    api.request(api.DetailCommon, {
      contentId: contentId,//콘텐츠ID
      // contentTypeId: contentTypeId,//관광타입(관광지, 숙박 등) ID
      defaultYN: "Y",//defaultYN,//기본정보 조회여부 Y
      firstImageYN: "Y",//firstImageYN, //원본, 썸네일 대표이미지 조회여부 Y
      // areacodeYN: "Y",//areacodeYN,//지역코드, 시군구코드 조회여부
      // catcodeYN: "Y",//catcodeYN,//대,중,소분류코드 조회여부
      addrinfoYN: "Y",//addrinfoYN,//주소, 상세주소 조회여부
      // mapinfoYN: "Y",//mapinfoYN,//좌표X, Y 조회여부
      overviewYN: "Y",//overviewYN,//콘텐츠 개요 조회여부
    }).then(function (res) {
      if (res.response.header.resultMsg === "OK") {
        let item = res.response.body.items.item;
        if (!Array.isArray(item)) item = [item];

        console.log("item DetailCommon: =>>>>>", item[0])
        WxParse.wxParse('homepage', 'html', item[0].homepage?item[0].homepage:"", that);
        WxParse.wxParse('overview', 'html', item[0].overview?item[0].overview:"콘텐츠 개요가 없습니다.", that);
        // item[0].isFavor = that.findFavor(item[0].contentid);

        that.setData({
          [`tabArray[0].resArray`]: item,
        })
        that.reqFinished(0);
        // util.hideLoading();
      } else { console.error("resultMsg != 'OK' : ", res.response.header.resultMsg) }
    })
    .catch(function (res) {
      util.hideLoading();
      console.error("catch : ", res)
    })
  },
  
  reqFinished(curTab) {
    util.hideLoading();
    return; // 우선 리턴....
    
    let tab = this.data.tabArray;
    tab[curTab].reqState = "finished";

    if( tab[0].reqState == "finished" && tab[1].reqState == "finished" && tab[2].reqState == "finished" ) {
      console.log("all finished ============= : ")
      util.hideLoading();
    }
  },
  
  
  

레이아웃

<!-- 공통정보 view -->
<block wx:if="{{TabCur==0}}">
  <view wx:for="{{tabArray[TabCur].resArray}}" wx:key="index">
    <view class="cu-card dynamic no-card">
  <!-- 기본정보 조회, 대표이미지 조회   -->
      <view class="cu-item shadow">
        <view class="cu-list menu-avatar">
          <view class="cu-item">
            <view class="cu-avatar round lg" style="background-image:url({{item.firstimage2}});">
              <text wx:if="{{!item.firstimage2}}" class="cuIcon-picfill text-gray"></text>
            </view>
            <view class="content flex-sub">
              <view class="text-bold text-cut">{{item.title}}</view>
              <view class="text-sm text-grey">최종수정일 : {{script.toDate(item.modifiedtime)}}</view>
            </view>
          </view>
        </view>
        <view class="padding-lr padding-bottom">
          <view>대 표 명 : {{item.telname}}</view>
          <view>대표전화 : {{item.tel}}</view>
          <view>홈페이지 : <template is="wxParse" data="{{wxParseData:homepage.nodes}}"/></view>
        </view>
  <!-- 주소, 상세주소 조회   -->      
        <view class="padding-lr padding-bottom">
          <view>우편번호 : {{item.zipcode}}</view>
          <view>주소 : {{item.addr1}}</view>
        </view>
  <!-- 대표이미지 조회   -->
        <view class="flex-sub padding-lr padding-bottom">
          <view class="bg-img only-img" style="background-image:url({{item.firstimage2}});">
            <view wx:if="{{!item.firstimage2}}" class="flex align-center justify-center bg-gray noImage">
              <text class="cuIcon-picfill text-gray"></text>
            </view>
          </view>
        </view>
<!-- 콘텐츠개요 조회   -->  
        <view class="padding-lr padding-bottom">
          <view class="wxParse"><template is="wxParse" data="{{wxParseData:overview.nodes}}"/></view>
        </view>
      </view>
    </view>
  </view>
</block>

실행화면

 

 

상단 컴파일 모드( compilation mode )에 테스트용 파라메터값 넣기

아래 이미지 처럼 파라메터값에 contentid=2614725&contenttypeid=12 넣어 사용하면 된다.

실행화면