2014-11-03 93 views
2

我正在爲我工​​作的公司的web應用程序工作,我有一個需要的窗體的問題。jquery - xeditable選擇源使用函數,使用緩存和本地存儲(indexedDB)

我在使用xeditable填充使用不同函數的數據的選擇列表時遇到了一些麻煩。

問題是正在執行的代碼填充選擇框不等待其他函數從本地存儲獲取數據並返回它,即使我使用的是緩存的(我不確定是否我正確使用了緩存/解析功能)。

這是我的代碼:

<a id="TypeID" data-type="select" data-pk="1966_TypeID" data-original-title="Please Select" data-pid="36" class="editable editable-click">3609</a> 

的jQuery:

function popSelectBox(PID) { 
    var rtn = []; 
    $.indexedDB('testDatabase').objectStore('Lookup').index('PID').each(function (i) { 
     var source = {}; 
     source.value = i.value.ID; 
     source.text = i.value.Name; 
     rtn.push(source); 
    }, PID).done(function (r, e) { 
     console.log(rtn); 
     console.log('popSelectBox function (I expect to see this first) - This section should complete before the makeEditable function'); 

     return rtn; 
    }); 
} 

function makeEditable() { 
    $('.editable').editable({ 
     validate: function (value) { 
      if ($.trim(value) === '') { 
       return 'This field is required'; 
      } 
      return false; 
     }, 
     success: function (response, newValue) { 
      console.log($(this).data('pk'), newValue); 
      //$(this).parent().css('background-color', 'green'); 
     }, 
     /**** this is the problem section of this function ****/ 
     source: function() { 
      //if the type is a select list then we need to populate it, this is done here 
      if ($(this).data('type') === 'select') { 
       var d = $.Deferred(); 
       $.when(d).done(function (v) { 
        console.log(v); 
        return v; 
       }); 
       d.resolve(popSelectBox($(this).data('pid').toString())); 
       console.log('makeEditable function (I expect to see this last) - This section should wait for the popSelectBox function to finish'); 
      } 
     } 
    }); 
} 

我也有一個小提琴這裏http://jsfiddle.net/f8otrayn/3/,顯示上方。 這個小提琴中包含一個本地存儲設置的例子,我設置了這個函數,但是我已經註釋掉了函數調用,你可以檢查代碼並取消註釋,如果你願意的話。

我正在尋找一種方法來等待,直到popSelectBox函數完成並返回數據,以便我可以使用該數據填充選擇框,我真的不想使用setTimeout,因爲有很多本地條目所以等待一段特定時間的存儲可能無法在所有情況下工作。

沒有人有任何想法

感謝

回答

1

我們不得不往下走不同的路線,而不是增加在最初建設形式的功能,我們增加了功能,以click事件

X編輯仍無法填充從函數的源,以便建議運行的代碼(在範圍內)之前從索引資料取得正確的值,並且增加了的結果陣列作爲源下面

代碼以供參考

$(document).on('click', '.editable-select', function(){ 
    var arr = []; 
    $.indexedDB('testDatabase').objectStore('Lookup').index('PID').each(function(i) { 
     if (i.value.Act === '1') { 
      arr.push({ 
       value: i.value.ID, 
       text:i.value.Name 
      }); 
     } 
    },$(this).data('pid').toString()).done(function(r, e){ 
     // 
    }); 

    /** setting the options has changed **/ 
    $(this).editable('option', 'source', arr); 
    $(this).editable('option', 'success', function(response, newValue) { 
     console.log($(this).data('pk'), newValue); 
    }); 
}); 

你會發現該設置荷蘭國際集團爲可編輯的選項已經改變,設置源是這樣的:

$('.editable').editable({ 
    validate: function() {...}), 
    success: function() {...}), 
    source: function() { 
     return arr; 
    } 
}); 

因爲某些原因沒有工作

0

從jQuery-IndexedDB的文件,據我瞭解,它的承諾有.done().fail().progress()方法,但令人驚訝的是,沒有.then()

這意味着jquery-indexeddb的promise沒有.then()提供的過濾能力,並且(除非有一些indexedDB的深不可測的特性),那麼將不可能返回所需數組的承諾。因此我們必須寫出通常歸類爲「延遲反模式」的東西。

popSelectBox()將是這樣的:

function popSelectBox(PID) { 
    var arr = [], 
     dfrd = jQuery.Deferred(); 
    $.indexedDB('testDatabase').objectStore('Lookup').index('PID').each(function(i) { 
     arr.push({ 
      value: i.value.ID, 
      text: i.value.Name 
     }); 
    }, PID).done(function() { // not too sure about `PID` here 
     dfrd.resolve(arr); 
    }).fail(dfrd.reject); 
    return dfrd.promise(); 
} 

.editable(...)插件,如果source選項是一個函數,那麼它必須返回值(陣列)通過popSelectBox()承諾,但重要的是,它本身不能退還承諾。因此,在makeEditable()中尋求的模式的基本特徵是(對於選擇元素)popSelectBox()被首先調用,然後.editable(...)響應於返回的承諾的分辨率被調用。

這有效地在當前碼中makeEditable()內向外,以:

  • 最外層:的每個元素是否爲<select>測試,並在適當的時候,要popSelectBox()的呼叫。
  • 最裏面:撥打.editable()。其中(恕我直言)最簡單的

的代碼可以寫在許多方面,是這樣的:

function makeEditable() { 
    var promises = $('.editable').map(function() { 
     var $that = $(this), 
      promise; 
     if ($that.data('type') === 'select') { 
      promise = popSelectBox($that.data('pid').toString()); 
     } else { 
      promise = $.when(); //dummy, ready-resolved promise. 
     } 
     return promise.then(function(arr) { 
      $('.editable').editable({ 
       validate: function() {...}), 
       success: function() {...}), 
       source: function() { 
        return arr || null; //assume it's safe to return null here for elements that are not selects. 
       } 
      }); 
     }); 
    }); 
    return $.when.apply(null, promises); //return a promise that will be resolved when all '.editable' elements have been initialized. 
} 

通過返回完成的承諾,調用makeEditable()能的功能,如果有必要,在所有元素都可編輯時做一些事情。

到底
+0

你好,這是十分感謝,它返回我們想要的東西,但是它不填充選擇框。 已經放置了幾個遊戲機以查看發生了什麼,看起來arr不在可編輯的功能範圍內,這很奇怪。 我不太確定它在做什麼,但在源代碼函數中添加控制檯不會返回任何東西,直到我單擊該元素,然後返回undefined。添加控制檯的上方或下方.editable功能回到我們所期望的 的PID在popSelectBox功能是IndexedDB的功能,我們有,它就像一個WHERE語句在SQL – 2014-11-04 12:32:31

+0

是'有史以來popSelectBox'調用,並承諾得到解決? – 2014-11-04 13:19:24

+0

並且做任何非選擇變得可編輯? – 2014-11-04 13:25:52