1. 程式人生 > >apicloud搜尋框的實現與踩坑

apicloud搜尋框的實現與踩坑

要求如下圖:

一、實現思路:
    1、開啟frame時,獲取儲存的資料(getStorage),放入建立的陣列中,遍歷該陣列將item展示出來。有記錄時,顯示記錄,沒有記錄時顯示空;
    2、最多十條記錄,記錄用 setStorage 儲存起來,並放在陣列中,最後搜尋的記錄在最前面;後面搜尋的記錄如果之前有,刪除之前的記錄,在陣列第一條新增。每點選一次 search (軟鍵盤搜尋鍵),記錄一條。
    3、點選記錄時,內容顯示在 input 輸入框中,並直接搜尋;被電擊的該條資料放到陣列第一位。
    4、點選垃圾桶圖示,清空陣列和被快取的資料

二、踩坑環節:

    1. 在開發中開發者在除錯時快取往往沒能清空
    (我在apploader上除錯沒有什麼好的清除快取的方法,只有2個選擇:
        第一,需要清除快取時,程式碼最前加 $api.clearStorage(),同步到手機一次;然後去掉該程式碼,重新進入一次。

        第二,解除安裝apploader,重新安裝,因為多次解除安裝安裝,安裝包先不刪除。)

    2. 使用者在剛剛開始使用app時,是沒有任何快取的資料的,並且沒有 keyWord 這個索引值。此時開啟frame 獲取不到快取會報錯。對此,可以在開啟frame 時setStorage傳入一個快取值,在存入陣列時將該資料刪除即可。

    if(!$api.getStorage('keyWord')){
	$api.setStorage('keyWord', '孍');
    }

        此處最好傳入生僻字,以免使用者重複到該詞。

    3. 這一點是我在開發中遇到的最難受的bug,當 arrHistory 值為空時,系統判定它不為陣列,所以要先將它轉化成陣列:

// 載入歷史搜尋
var searchHistory = [];
function hasHistory(){
    searchHistory = $api.getStorage('keyWord');
    if(JSON.stringify(arrHistory)=='undefined'){
        searchHistory += ' ';
        searchHistory = searchHistory.split(',');
    }
    if(searchHistory.length==1 && searchHistory[0]=='孍' || searchHistory.length==0 ||!searchHistory){
        $api.byId('history-box').innerHTML = '';
    }else{
        var historyHtml = '';
        historyHtml += '<p>'
            +'<span class="history fs14 pl5 c000">歷史搜尋</span>'
            +'<i class="iconfont icon-lajitongshanchu history-icon fs18" onclick="clearHistory()" Tapmode></i>'
            +'</p>'
            +'<div class="history-list fs12">';
        for(var i in arrHistory){
            historyHtml += '<span class="history-item item" onclick="historyItemToList('+i+')">'+arrHistory[i]+'</span>';
        }
        historyHtml += '</div>';
        $api.byId('history-box').innerHTML = historyHtml;
    }
}

        js程式碼中宣告的 var arrHistory=[ ] 陣列,在函式中讀取到為 undefined,這是因為在剛剛進入時沒有快取值可獲取。設定了剛進入就初始一個快取值就行。

        以下程式碼將監聽到的 關鍵詞 存入陣列並存入快取中,此時通過arrHistory=$api.getStorage('keyWord');獲取到的 arrHistory 是有問題的,不是陣列型別,不能直接使用;也不是字串型別,所以要先轉化成字串型別,再用split 轉化為陣列型別。再對陣列進行操作,加入新的關鍵詞到陣列最前,刪除不必要的關鍵詞。

// 監聽 win 頁面的關鍵詞
function listenShopKeyWord(page) {
    api.addEventListener({
        name: 'shopkeyWord'
    }, function(ret, err){
        keyWord = ret.value.keyWord;
        if(keyWord){
            document.getElementById("listData").innerHTML = '';
            searchKeyWord(keyWord, page);
            commonGetStorage(keyWord);
        }else{
            hasHistory();
        }
    });
}
// 搜尋關鍵字function searchKeyWord(keyWord, page){
    api.ajax({
        url: url,
        method: 'post',
        dataType: 'json',
        data: {
            values: params
        }
    },function(){
        if(ret){
            //正常處理 或 展示搜尋結果
        }else{
            alert('請求錯誤');
        }
    });
}
// 搜尋函式公用
function commonGetStorage(content){
    if($api.getStorage('SEARCH_KEY')){
        searchHistory = $api.getStorage('keyWord');
        searchHistory += '';
        searchHistory = searchHistory.split(',');
    } else {
        searchHistory = [];
    }
    // 搜尋的長度
    var SEARCH_MAX_LENGTH = 10;
    insertArray(
        searchHistory,
        content,
        SEARCH_MAX_LENGTH
    );
    $api.setStorage('keyWord', searchHistory);
}
// 比較新的 keyWord 與原陣列,選擇新增方式
function insertArray(arr, val, maxLen) {
    // 先查詢陣列有沒有val 值
    var index = arr.indexOf(val);
    // 如果是第一條資料就不做操作
    if (index === 0) {
        return
    }
    // 如果有 val值 就先刪掉再插入
    if (index > 0) {
        arr.splice(index, 1)
    }
    // 沒有就直接插入
    arr.unshift(val);
    // 去除 第一個預設歷史值
    var i = arr.length-1;
    if(arr[i]=='孍'){
        arr.splice(i, 1);
    }
    if(arr[i]==''){
        arr.splice(i, 1);
    }
    // 超過陣列的最大數量就把最後一個刪掉
    if (maxLen && arr.length > maxLen) {
        arr.pop();
    }
}
// 點選歷史搜尋跳轉到list
function historyItemToList(i){
    var keyWord = searchHistory[i];
    api.sendEvent({
        name: 'shopClickItem',    //然後在 win 頁面監聽此事件並獲取到 keyWord ,將關鍵詞放到input
        extra: {
            keyWord: keyWord
        }
    });
}
// 清除歷史搜尋
function clearHistory(){
    document.getElementById('listData').innerHTML = '';
    searchHistory = ['孍'];
    $api.setStorage('keyWord', []);
}
function searchKeyWord(keyWord, page){
    api.ajax({
        url: url,
        method: 'post',
        dataType: 'json',
        data: {
            values: params
        }
    },function(){
        if(ret){
            //正常處理 或 展示搜尋結果
        }else{
            alert('請求錯誤');
        }
    });
}
// 搜尋函式公用
function commonGetStorage(content){
    if($api.getStorage('SEARCH_KEY')){
        searchHistory = $api.getStorage('keyWord');
        searchHistory += '';
        searchHistory = searchHistory.split(',');
    } else {
        searchHistory = [];
    }
    // 搜尋的長度
    var SEARCH_MAX_LENGTH = 10;
    insertArray(
        searchHistory,
        content,
        SEARCH_MAX_LENGTH
    );
    $api.setStorage('keyWord', searchHistory);
}
// 比較新的 keyWord 與原陣列,選擇新增方式
function insertArray(arr, val, maxLen) {
    // 先查詢陣列有沒有val 值
    var index = arr.indexOf(val);
    // 如果是第一條資料就不做操作
    if (index === 0) {
        return
    }
    // 如果有 val值 就先刪掉再插入
    if (index > 0) {
        arr.splice(index, 1)
    }
    // 沒有就直接插入
    arr.unshift(val);
    // 去除 第一個預設歷史值
    var i = arr.length-1;
    if(arr[i]=='孍'){
        arr.splice(i, 1);
    }
    if(arr[i]==''){
        arr.splice(i, 1);
    }
    // 超過陣列的最大數量就把最後一個刪掉
    if (maxLen && arr.length > maxLen) {
        arr.pop();
    }
}
// 點選歷史搜尋跳轉到list
function historyItemToList(i){
    var keyWord = searchHistory[i];
    api.sendEvent({
        name: 'shopClickItem',    //然後在 win 頁面監聽此事件並獲取到 keyWord ,將關鍵詞放到input
        extra: {
            keyWord: keyWord
        }
    });
}
// 清除歷史搜尋
function clearHistory(){
    document.getElementById('listData').innerHTML = '';
    searchHistory = ['孍'];
    $api.setStorage('keyWord', []);
}

    因為 searchHistory 為空會報錯,所以只能賦個偏僻字,用 $api.setStorage('keyWord', []); 而不用 clearStorage 清空快取是因為 app 中快取往往不止這一類。

    最後,感覺自己目前寫的這些並不令人滿意,待有更高質量的程式碼再來更新。同行如果有更好的方法,希望留言一起探討,一起進步。