【總結】項目實踐2016.12.20

項目總結【中東許願池】

@(項目總結)[中東許願池, 2016-12-20]html

[TOC]java

zencms的使用

  • <cms:custom></cms> 標籤包裹須要配置的內容react

    • name:這段文本的名稱
    • fields:配置文案列
    • defaultRow:默認行數
    • row:最多行數
    • id:默認生成
  • 在結構中 <%=data%> 方式展現數據android

<cms:custom name="表格" alias="alias" fields="name:實物獎品,pic:對應禮物,des:商品描述,num:星星數量" row="10"  defaultRow="1"  id="2809c7905e23fa827e53354b63e0d259">
	<% data.forEach(function(item, index){ %>
		<dd>
			<p class="name"><%=item.name%></p>
			<p class="pic">
				<img src="<%=item.pic%>" />
				<em><%=item.des%></em>
			</p>
			<p class="num"><%=item.num%></p>
		</dd>
	<%})%>
</cms>
  • 對應後臺編譯效果 後臺效果圖

多語言的使用

可配置多語言key、替換邏輯中固定名稱、支持標籤在多語言中的運用ios

使用前的配置

  • 在邏輯代碼中lang.template('須要翻譯的文案') 代替須要翻譯的文案
  • 運用 zenbone lang key 命令 key 文件
  • google doc 中添加 key 值和須要翻譯語言碼
  • 點擊菜單:File->Publish to the web發佈文件
  • 選中 Published content & settings 配置:Automatically republish when changes are made。 每次變動都會自動發佈文件,更新文件內容。
  • package.json 文件中配置 googleSpreadsheetId(Google Spreadsheet Id)和 googleSpreadsheetIndex(Google Spreadsheet中sheet的索引)
  • 使用 zenbone lang file 命令生成翻譯文件
  • 將翻譯文件複製到對應的多語言包中

字符串的使用

  • 調用 lang.template('須要翻譯的文案')

翻譯中有須要替換的內容

  • 調用 {lang.template('Up號: <%=code%>', { code: data.upliveCode})}

翻譯中插入標籤

  • 調用 <ul className="rule" dangerouslySetInnerHTML={{__html: lang.template('活動規則')}}></ul>

  • Google doc 中的配置

Google doc 配置示意

Google doc 配置示意2

  • package.json 文件中配置
"googleSpreadsheetId": "1EBZIWdCrGVmtxfxdvdETWnmlwpghPe1o1FbZjdnE4AU",
  "googleSpreadsheetIndex": 0,
  • 普通字段調用
<p>{lang.template('活動時間')}</p>
  • 可替換一部份內容調用
<span className="uplivecode">
	{lang.template('Up號: <%=code%>', { code: data.upliveCode})}
</span>
/********lang文件中這樣設置*********/
'Up號: <%=code%>': 'Up賬號 : <%=code%>'
  • 帶標籤文本
<ul className="rule" dangerouslySetInnerHTML={{__html: lang.template('活動規則')}}></ul>

/************lang文件中這樣設置***********/
"活動規則":"<li>活動規則</li>" + 
            "<li>1.在活動期間內總U幣高過十萬,且活動開始前已有U幣不高於九萬五。</li>" + 
            "<li>2.獎勵將在活動結束後聯絡到相關主播發放</li>"  + 
            "<li>3.活動數據會有延遲,依照官方時間為準。</li>",

項目總結2016-12-20

@(個人第一個筆記本)[十萬主播項目得來][up-lakhanchor]web

[TOC] @(萬聖節活動項目得來)[2016-12-20, up-halloweenrank]ajax

路由的使用

管理各個不用頁面的跳轉json

  • 引用react-router 組件
import { Router, Route, hashHistory, useRouterHistory} from 'react-router';
import { createHashHistory } from 'history';
const appHistory = useRouterHistory(createHashHistory)({ queryKey: false });
  • 渲染路由
    • path="url#後的頁面名稱"
    • component={對應模塊名稱}
render((
	    <Router history={appHistory}>
	        <Route path="/" component={Home}/>//沒有任何參數是爲Home模塊
	        <Route path="/main" component={Main}/>//參數是main時爲Main模塊
	        <Route path="*" component={Home}/>//默認設置爲Home模塊(*--爲其餘全部的參數下)
	    </Router>
	), $('#wrap')[0]);

配置全局信息

根據需求修改從服務器請來的參數作爲全局屬性在業務中使用api

  1. 請求數據
  2. 截取請求數據中業務中須要的一段
  3. 改變請求數據中須要改變的數據
  4. 將改變後的數據付給新的全局數據
var getActivityInfo = function (){//請求數據
	let activityId = url.query('activityId');
    let promise = http.fetch({
        url: api.getActivityInfo(),
        data:{
             activityId
        }
    })
    return promise;
}
getActivityInfo().done((res)=>{

	let periodList = res.data.periodList.slice(1);  //獲取請求數據中須要的一段

	window._global_periodList = periodList.map((item, index) =>{//將修改後的數據付給window._global_periodList,periodList爲一個數組須要循環改變數組中的每一項
		let _lang = lang.getLangType();
		let activityTime;
		let dateStart,dateEnd;
		if (_lang == 'areg'){//更改須要的數據
			dateStart = formatData(item.startTime*1000, 'dd/MM HH:mm',12);
			dateEnd = formatData(item.endTime*1000, 'dd/MM HH:mm',12);
			activityTime = dateStart +'——' +dateEnd ;
		} else {
			dateStart = formatData(item.startTime*1000, 'MM月dd日 HH:mm');
			dateEnd = formatData(item.endTime*1000, 'MM月dd日 HH:mm');
			activityTime = dateStart +'——' +dateEnd ;
		}
		return {//返回一個對象,這個對象就是須要的數據
			title: lang.template('第' + (index + 1 )+ '天'),
            day: index + 1,
            startTime: item.startTime ,
            endTime: item.endTime ,
            activityTime: activityTime
		}
	});
})
  • 調用方式
console.log(global_periodList)
/**********顯示數據*************/
[
	{
		title:第一天,
        day: 1,
        startTime:1408372402 ,
        endTime:14239789 ,
        activityTime: 10月28日 22:00——10月29日 21:59
	},
	{
		title:次日,
        day: 2,
        startTime:1408376789 ,
        endTime:1423668999 ,
        activityTime: 10月29日 22:00——10月30日 21:59
	}
]

活動倒計時

從服務器獲取每日開始、結束時間、當前時間戳,顯示距離當天活動結束時間倒計時,tab默認選中當天。數組

設置當天爲默認選中的第幾天

在配置信息中填寫對應數組 index+1 爲第幾天

  1. 設置默認選中爲第一天
  2. 找出如今是第幾天
    • 循環配置信息
    • 當前時間小於該項結束時間而且大於該項開始時間時設置項中的當前天數爲選中狀態
    • 若是當天超出整個活動天數設置最後一個爲選中狀態
      • 活動的最後天爲位置信息中length-1的天數

距離每日活動結束倒計時

  1. 設置默認倒計時閾值false
  2. 計算當天還剩多少時間
    • 當天的結束時間戳 - 當前的時間戳
  3. 在有當天倒計時時間狀況下將倒計時閾值開啓true,並調用倒計時

  • 引用倒計時插件
import Timer from './base/timer';
constructor(props) {
        super(props);
        this.state = { //設置默認閾值
            isDisplayDaojishi: 0,
            currentDay: 1
        }
    } 
    
    getServerTime(serverTime){ //serverTime 從每一個活動榜單接口中返回當前時間戳
        let self = this;
        let cutter;
        let activityEndTime;
        let activityInfo = _global_periodList;

        $.each(activityInfo, function(index , item){
            let startTime = item.startTime;
            let endTime = item.endTime;
            if (serverTime >= startTime && serverTime < endTime){//獲取如今是活動的第幾天
                cutter = endTime - serverTime;//計算當天距離活動還有多少時間
                self.setState({
                    currentDay: item.day//設置當前項中天數爲默認選中的第幾天
                });
                return false;
            }
        });
        
        activityEndTime = activityInfo[activityInfo.length-1]['endTime'];//最後一天的結束時間

        if(serverTime >= activityEndTime){//若活動已經結束最後一天作爲當前選擇天
            self.setState({
                    currentDay: activityInfo[activityInfo.length-1]['day']
                });
        }

        if (cutter) {//若是有當天倒計時時間開啓倒計時閾值
            this.setState({
                isDisplayDaojishi: 1
            });
            self.daojishi(cutter);
        }
        loading.hide();
    }
    daojishi(cutter){ //調用倒計時插件
        
        var timer = new Timer({
            remainTime: cutter,
            // remainTime: 10,
            selector: {
                day: '#day',
                hour: '#hour',
                minute: '#minute',
                second: '#second'
            },
            isDoubleBit: true
        });

        timer.on('end', function() {})
    }
    render() {
        let daojishiDom;

        if (this.state.isDisplayDaojishi) { //倒計時閾值開啓時顯示倒計時
            daojishiDom = (
                <div className="daojishi">
                    <p className="daojishi-title">{lang.template("今日榜單活動結束還有")}</p>
                    <div className="daojishi-time"><em id="day">10</em>{lang.template("天")}<em id="hour"></em>{lang.template("小時")}<em id="minute"></em>{lang.template("分")}<em id="second"></em>{lang.template("秒")}</div>
                </div>
            );
        }
        return (
            <div className="carwar">   
                
                {daojishiDom}
                <div className="daily-billboard">
                    <DailyBillboard ref="dailyBillboard" tabs={_global_periodList} getServerTime={this.getServerTime.bind(this)} currentDay={this.state.currentDay} getActivityInfo={this.state.getActivityInfo}/>
                </div>
            </div>
        );
    }

顯示所有數據中的某一部分

請求回來的數據只顯示前10名,前三名和4-10的UI不用。若所有數據多於10只顯示9條,最後顯示點擊查看更多

只取全部數據中的前十個

  • 請求數據的 pageSize 設置爲10(須要前幾設成幾)

從前十中分別截取1-三、4-10

  • dataArr.slice(0, 3)獲取數組中的1-3項、dataArr.slice(3) 獲取數組中第四項及之後

多餘10條時顯示更多

  • 判斷數據長度,若是大於須要顯示的長度(10減3)list 中添加顯示更多模塊

loadData() { //請求數據
     let pageSize = this.props.maxSize + 1;//請求數據長度爲須要的數據數
     let nextPage;
     let promise = http.fetch({
         url: api.getBillBoard(),
         data: {
             page: 1,
             pageCount: pageSize
         }
     });
     promise.done((res) => {
         if (res.code == 'SC_SUCCESS') {
             this.setState({
                 dataReady: true,
                 dataArr: res.data.hostList
             });
         }
     });
 }
render() { //渲染
   let $list;
   let dataArr = this.state.dataArr;
   let top3Arr = dataArr.slice(0, 3);//截取1-3的數據
   let top4to10Arr = dataArr.slice(3);//截取3之後的數據

   $list = (
       <div>
           <div className="top3">//1-3的渲染
               <Top3 list={top3Arr}/>
           </div>
           <div className="top4to10">//3之後的渲染
               { top4to10Arr.length > 0 ? <Top4to10 list={top4to10Arr} maxSize={this.props.maxSize - 3}/>: null}
           </div>
       </div>
   );

	return (
	    <div className="board-list-wrapper">
	        <div className="board-list">
	            {$list}
	        </div>
	    </div>
	);
}
  • 4-10的模塊(數據多於10時顯示顯示點擊更多)

從父組件傳入數據,且傳入的數據不是一次性,會改變是須要調用 reactcomponentWillReceiveProps方法

constructor(props){
        super(props);

        this.state = {
            list: props.list//將從外面傳進來的數據設置爲list
        }
    }
componentWillReceiveProps(props) {//從父組件傳入數據,且傳入的數據不是一次性,會改變是須要調用componentWillReceiveProps方法
    this.setState({
        list: props.list
    });   
}
render(){
    let dataArr = this.state.list;
    let maxSize = this.props.maxSize;
    let $list = [];

    if (dataArr.length > maxSize) {//得到到的數據大於需求數據長度
        let arr  = dataArr.slice(0, maxSize);//截取對應數據

        $list = arr.map(function(item, index){
            return <UserItemOther key={item.uid} rank={index + 4} data={item}/>
        });
        
        $list.push (<MoreUserItem key="more"/>);//添加查看更多模塊
    } else {//得到到的數據不大於需求數據長度
        $list = dataArr.map(function(item, index){
            return <UserItemOther key={item.uid} rank={index + 4} data={item}/>;
        });
    }
    
    return (
        <div className="top4to10-list">
            {$list}
        </div>
    );
}

tab防止其餘選項卡下滑滾動

  • 根據點擊當前選項,從父模塊中傳入 selectedIndex
  • selectedIndex 等於當前 index 時設置當前選項中的可滾動閾值爲開
  • 當可滾動閾值爲開開始調用下滑滾動事件

  • 父模塊
onSelect = (index, e)=>{ //將點擊時數組的index設置成selectedIndex
        this.setState({
            selectedIndex: index
        });
    }
    render(){
        let self = this;
        let hostTabs = this.props.tabs;

        return (
            <div className="daily-list-wrapper">
                    <Tabs  onSelect={this.onSelect} >                            
      
                    {
                        hostTabs.map(function(tab, i){
                            let enable;
 /*
 *若是數組的索引值與selectedIndex的值相等說明如今展現的爲當前選中的tab
 * 設置當前選中的tab中的enable爲true,其餘的爲false
 */
							enable = (i == self.state.selectedIndex) ? true: false;                            
                            return (
                                <TabPanel key={i}>
                                    <DailyList scrollEnable={enable}/>
                                </TabPanel>
                            )
                        })
                    }
                    </Tabs>
                </div>
        );
    }
  • 子模塊
scrollList(e){
        let self = this;
        let timer;

        $(window).on('scroll',function(){
            if (self.props.scrollEnable) {//當scrollEnable閾值爲true時才執行下拉滑動事件
                timer && clearTimeout(timer);
                timer = setTimeout(function () {
                
                    if (self.dataOver || self.isLoad) {
                        return;
                    } else {
                        let  body = document.body, docElement = document.documentElement;
                        //700 在頁面滑到底部前700px就能夠加載,增長交互流暢性
                        if(body.scrollTop > docElement.offsetHeight - docElement.clientHeight - 700){
                            self.getData();
                        }
                    }
                } , 500);
            }
       })  
    }

tab

切換選擇菜單的同時切換接口的請求地址

當須要清楚之前的dom,在更改成新dom

  • 設置一個閾值,當點擊時setState將閾值關閉,在setState的回調中將閾值開啓,並set相應的屬性值
  • 在render時經過閾值和空div,清楚過去的dom,在setState時渲染新的dom
constructor(props) {
        super(props);
        this.state = {//設置tab須要的配置
           tab:[
                { 
                    name:lang.template('衝刺中'),
                    url:api.getStriveInfo()
                },
                { 
                    name:lang.template('已達成'),
                    url:api.getFinishInfo()
                }
           ],
           selectId:0,//設置默認參數
           url:api.getStriveInfo(),
           isMount:true//設置中間轉態的閥門
        };
    }
    chooseTab =(index,url)=> {//點擊tab是改變state對應的值
        this.setState({
             isMount: false//當setState時設置閥門爲false
        }, function(){//setState後的回調
           this.setState({//setState成功後再打開閥門,設置對對應的屬性值
                selectId:index,
                url:url,
                isMount: true
            }) 
        })
        
    }
    render() {
        let self = this;
        let $tab = [];
        
        this.state.tab.forEach(function(item,index){//渲染tab,並根據數組的index是否與selectId相等決定選中狀態
            $tab.push(
                <i className={self.state.selectId == index ?item.style+ " checked":item.style}
                    key = {index}
                    onClick={self.chooseTab.bind(this,index,item.url)}
                >{item.name}</i>
            )
        })
  

        if(this.state.isMount) {//選中狀態的閾值(react對比dom樹)
            return (
                <div className="r-wrap">
                    <div className="banner">
                        <div className="bannerImg">
                            <p>{lang.template('活動時間')}</p>
                        </div>
                        <ul className="rule" dangerouslySetInnerHTML={{__html: lang.template('活動規則')}}></ul>
                        <ol className="award" dangerouslySetInnerHTML={{__html: lang.template('活動獎勵')}}></ol>
                    </div>
                    <div className="rank">
                        <h1 className="tab">
                            {$tab}
                        </h1>
                        <List goProfile={self.goProfile} url={this.state.url}/>
                    </div>
                    <Refresh />
                </div>
            );
        } else { //切換tab時清楚上一個dom
            return <div></div>;
        }
        
    }

請求數據下拉加載更多

constructor(props) {
      super(props);
       this.state = {//加載、沒有數據等狀況須要顯示在頁面中的閾值
          list:[],
          page:1,
          url:this.props.url,
          dataLoading:true,
          empty:false,
          dataEnd:false
       };
       //防止異步請求時的閾值,只在邏輯代碼中使用
       this.isLoading = true;
       this.dataOver = false;
   }
   componentDidMount(){//數據變動時調用下滑滾動事件
	 $(window).off('scroll');
   }
   componentWillUnmount() {//清楚滑滾動事件
     $(window).off('scroll');
   }
   getListInfo() {
        let self = this;
        let url = this.state.url;
        let page = this.state.page;//page每次都會有更改
        let pageSize = 25;      
        let promise = http.fetch({
            url: url,
            data:{
                index:page,
                pageCount:pageSize
            }
        });
        
        promise.done(function(res){

            if (res.code == 'SC_SUCCESS') {

                if (res.data.length < pageSize) {//當前頁數組長度小於pageSize,說明是最後一頁
                    self.dataOver = true;
                    self.setState({
                        dataLoading:false,
                        dataEnd:true
                    })
                } 
                if (page == 1) {
                    if (res.data.length == 0) {//當page==1時,數組長度爲0,說明沒有數據
                        self.setState({
                            empty:true,
                            dataLoading:false,
                            dataEnd:false
                        })
                    };
                };
                nextPage = page + 1;//請求一次事後將page增長1
                self.setState({
                    list:self.state.list.concat(res.data),//將每次請求過來的數據追加到數組中
                    page:nextPage//將新的page state到page
                }); 
                self.isLoading = false;  
            }
        });
        
    }
    scrollList(){
        let self = this;
        let page = this.state.page;
        let timer;
        $(window).off('scroll');
        $(window).on('scroll' , function () {
            timer && clearTimeout(timer);
            timer = setTimeout(function () {
                if (self.dataOver || self.isLoading) {//當沒有數據或者正在 請求數據時,不執行下拉加載
                    return
                } else {
                    var body = document.body, docElement = document.documentElement;
                    // 700 在頁面滑到底部前700px就能夠加載,增長交互流暢性
                      if(body.scrollTop > docElement.offsetHeight - docElement.clientHeight - 700){

                            self.isLoading = true;
                            self.getListInfo();

                       }
                };
                
            } , 300);
        });
    }

更新列表

頁碼數設置爲1,每頁請求的長度爲當前數據的長度

componentDidMount() {//數據變動時設置全局事件
    let self = this;
      $.channel.on('refreshAll', function(){
          self.refetch();
      });
  }
  componentWillUnmount() { //解綁全局事件
      $.channel.off('refreshAll');
  } 
 refetch() {
        let self = this;
        let pageSize = this.state.list.length;//請求數據長度爲當前數據長度
        let promise = http.fetch({
            url: urls,
            data:{
                index:1,//請求第一頁
                pageCount:pageSize
            }
        });

        promise.done(function(res){

            if (res.code == 'SC_SUCCESS') {
                self.setState({
                    list:self.state.list.concat(res.data)//將刷新請求過來的數據設置爲渲染數據
                }); 
                self.isLoading = false;  
            }
        });
        
    }

@(2016.12.15)

從URL上獲取具體參數

query(name, scope) {
	var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"),
		scope = scope || 'search',
		r = location[scope].substr(1).match(reg);
	if (r != null) {
		return unescape(r[2]);
	}
	return null;
}
  • 調取方式
//url:www.baidu.com?sid=1
 var sid = query("sid");
 console.log(sid);// 1

獲取平臺類型

返回的平臺類型: weixin, weibo, qq

getPlatform() {
		let [ua, pl] = [navigator.userAgent, 'other'];

		if (ua.match(/micromessenger/i)) {
			pl = 'wechat';
		} else if (ua.match(/qq/i)) {
			pl = 'qq';
		} else if (ua.match(/weibo/i)) {
			pl = 'weibo';
		} 

		return pl;
	}
  • 調取方式:
//在微信中
    	platform = getPlatform();
    	console.log(platform) //weixi

得到客戶端的版本號

讓客戶端在ua中添加對應字段和版本號(sfans)

getVersion() {
	var ua = navigator.userAgent;
	var reg = /sfans\/(.+?) /i;
	return reg.exec(ua)[1];
}
  • 調取方式
consoel.log(getVersion()) //sfans

獲取當前系統類型

getSystem() {
    	let ua = navigator.userAgent;
    	return /(iPhone|iPad|iPod|iOS)/i.test(ua) ? 'ios' : /[aA]ndroid/i.test(ua) ? 'android' : 'pc';
}
  • 調取方式

    //在iOS中
      console.log(getSystem()) //ios

時間戳變爲固定格式的日期

支持上下午

  • time:時間戳
  • pattern:時間格式
  • hourType:時間類型(12,24)
formatData =(time, pattern, hourType)=> {
        var dateObj = new Date(time);
        
        hourType = hourType || 24;

        if (!pattern) {
            pattern = "yyyy-MM-dd HH:mm:ss"; 
        }
        var val, result;
        var func = function(matched) {
            return matched.length == 2 && val < 10 ? ("0" + val) : val;
        };

        result = pattern.replace(/y{2,4}/, dateObj.getFullYear()); // the year
        val = dateObj.getMonth() + 1; // the month
        result = result.replace(/M{1,2}/, func);
        val = dateObj.getDate(); // the date
        result = result.replace(/d{1,2}/, func);
        
        if (hourType == 12) {
            val = dateObj.getHours(); // the hour
            let isAm = 1;

            if (val > 12) {
                result = result.replace(/H{1,2}/, function(matched){
                    if (matched.length == 2) {
                        if (val > 12) {
                            val = val - 12;
                            if (val < 10) {
                                val = '0' + val;
                            }
                            isAm = 0
                        } else if(val < 10){
                            val = '0' + val;
                            isAm = 1;
                        }
                    }
                    return val;
                });
                val = dateObj.getMinutes(); // the minute
                result = result.replace(/m{1,2}/, func);
                val = dateObj.getSeconds(); // the second
                result.replace(/s{1,2}/, func);
            } else {
                result = result.replace(/H{1,2}/, func);
                val = dateObj.getMinutes(); // the minute
                result = result.replace(/m{1,2}/, func);
                val = dateObj.getSeconds(); // the second
                result.replace(/s{1,2}/, func);
            }

            if( isAm ) {
                result +='am'
            } else {
                result +='pm';
            }
        } else {
            val = dateObj.getHours(); // the hour
            result = result.replace(/H{1,2}/, func);
            val = dateObj.getMinutes(); // the minute
            result = result.replace(/m{1,2}/, func);
            val = dateObj.getSeconds(); // the second
            result.replace(/s{1,2}/, func);
        }

        return result;
    }
  • 調取方式

    console.log(formatData(時間戳,'yyyy年MM月dd日 HH:mm',12))//2016年12月12日 12:12pm

圖片輪播

引用SwipeSlide

class Banner extends Component {

    static defaultProps = {
        selectIndex: 0 // 默認第一項,索引值0
    }
    constructor(props) {
        super(props);
        
        let selectIndex = 0;
        
        if ('selectIndex' in props) { //插件中的當前圖片索引
            selectIndex = props.selectIndex;
        } else {
            selectIndex = props.selectIndex;
        }

        this.state = {
            selectIndex: selectIndex //state當前圖片索引
        };
    }
    componentDidMount(){
        let self = this;
        if (this.props.banner.length == 1) {
            $(".dot").hide();//一張圖片是不顯示圓點
        } else {
            this.timer = setTimeout(()=>{
                // 圖片輪播插件調用 
				// $(this.refs.content)包含圖片的大容器
                this.swipeSlide = new SwipeSlide($(this.refs.content), {
                    continuousScroll: true,
                    autoSwipe : true,
                    speed : 5000,
                    transitionType: 'ease-in',
                    callback: function(index){
                        self.setState({
                            selectIndex: index //回調後state索引
                        });
                    }
                });
     
            }, 500);
        };
    }
    render() {
        let self = this;
        let imgArr = this.props.banner;
        let $li = [],cls;

        return (
            <div className="banner-slide-wrap" ref="content" style={{opacity: this.state.opacity}}>
                    <ul className="slide-list">
                    {   
                        imgArr.map((item, i) => {  //循環渲染單張圖片 容器
                            let cls = 'slide-item';
                            cls += this.state.selectIndex == i ? ' selected' : '';
                            return <li className='slide-item' key = {i} onClick={self.goBanner.bind(this,item.redirect)}><img src={item.images + '?imageView2/1/w/320/h/154'} /></li>
                        })
                    }
                    </ul>
                    <div className="slide-dots"> //圓點容器
                    {
                        imgArr.map((item, i) =>{
                            var cls = 'dot';
                            cls += this.state.selectIndex == i ? ' selected' : '';

                            return (
                                <span key={i} className={cls}></span>
                            );
                        })
                    }
                    </div>
                </div>
        ) 
    }
}

防止重複點擊

列表中點擊一個後其餘全部按鈕均不可重複點擊

class List extends Component {
    constructor(props) {
        super(props);
        self.clicked = false ;//設置默承認點擊狀態(已點爲false)
    }
    postTask = (item) => {//請求服務器接口
		let promise = $.ajax({
				url: urls,
				type: 'GET',
				data:{
					index:page,
					pageSize:25
				},
				dataType: 'json'
			});

			promise.done(function(res){

				if (res.code == 'SC_SUCCESS') {

					alert("成功")
				} else {
					alert("系統錯誤")
				} 
				 self.clicked = false;//獲取數據成功設置回可點狀態
			});
			promise.fail(function(res, type){
				self.clicked = false;//數據獲取失敗設置回可點狀態
				alert("獲取數據失敗")
			}); 
    }
   
    
    goTask =(data)=> {
        let self = this;
        let platform = client.getPlatform();
      
        if (self.clicked || data.status == 1) {//當已點過狀態或者已作任務狀態不可點擊
            return ;
        } else {
            self.clicked = true ;//點擊進去之後設置爲已點擊過狀態
        };   
    }
    render() {
        let self = this;
        return (
            <ul className="list" >
               <li onClick={self.goTask.bind(this,item)}></li>
            </ul>
        ) 
    }
}

在list 中修改其中一項的屬性值

  • 數據機構:
list:[
			{
				name:"aaa",
				status:0
			},
			{
				name:"bbb",
				status:0
			}
	]
  • 修改aaa的status爲1
list.forEach(function(data,i){
		   if ( data.name == "aaa" ) {
		          data.status = 1;
		      };
		  });
		  self.setState({
		      listInfo:list
		  })
```	  

* 修改後的數據變爲
list:[
		{
			name:"aaa",
			status:1
		},
		{
			name:"bbb",
			status:0
		}
]
***

###PB文件的使用

>- 引入PB轉化插件c-pbajax
>- 下載相應的PBJs編輯後的文件
>- 在HTML中引入種子文件

` 
 `

<script src="http://h.cdn.pengpengla.com/h5lib/3.0.0/js/protobuf.js></script>

/以上引入到HTML種子文件中/ import pbajax from 'c-pbajax';//引入統一的編譯插件 import infoListpb from './pb/taskslistpb';//引入業務文件 import publicpb from './pb/publicpb';//引入說明文件 //https://star-service.pengpengla.com/t/tasks/act /*"package": "Banner.List",

  • "options": {
  • "objc_class_prefix": "BannerList",
  • "java_package": "com.asiainno.starfan.proto"

*/ }, pbajax.do( { service: 'sfanservice', //項目PB目錄 api: '/t/tasks/act',//項目文件地址 header: { usertoken:_global_token//header中傳入的參數 }, inchina: 1 }, new tasksactpb.Tasks.Act.Request({ //參數 version: vc, sid:sid, taskId:item.id }),
function(res){// success var dataWrap = publicpb.Result.decode(res), data; if (dataWrap.code == 1) { data = tasksactpb.Tasks.Act.Response.decode(dataWrap.data.value);//對應文件中的package console.log(item); } }, function(){}, function(){//服務器掛了 console.log("服務器掛了"); } );

----------
相關文章
相關標籤/搜索