2

Я работаю над веб-приложением для компании, в которой я работаю, и у меня есть проблема с формой, которая требуется.jquery - xeditable select source using function, используя дефферированное и локальное хранилище (indexedDB)

У меня возникли проблемы с заполнением списка выбора данными из другой функции с помощью xeditable.

Проблема заключается в том, что код, который выполняется для заполнения окна выбора, не дожидается, когда другая функция получит данные из локального хранилища и вернет его, хотя я использую defffered (я не уверен, что Я правильно использую функции deffered/resolve).

Это код, который у меня есть:

<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

в конце концов, мы должны были пойти по другому пути и вместо того, добавить функциональность, когда первоначально здание формы, мы добавили функциональность на событие щелчка

х редактируемой еще не в состоянии заселить источник из функции, так как это было предложено запускали код (в объеме), чтобы получить правильные значения от индексированной до и добавил массив результатов в качестве источника

код ниже для справки

$(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 не имеют фильтрующей способности, предоставляемой .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 не входит в сферу .идействующей функциональности, которая является странной. Я не совсем уверен, что он делает, но добавление консоли в исходную функцию ничего не возвращает, пока я не щелкнул элемент, а затем вернется в неопределенное состояние. Добавление консоли выше или ниже возвращаемой функции возвращает то, что мы ожидаем PID в функции popSelectBox - это функция indexedDB, которая у нас есть, она действует как оператор where в sql –

+0

Является ли 'popSelectBox' когда-либо вызываемым и выполняет ли его обещание ? –

+0

И делать какие-либо неизбираемые становятся доступными для редактирования? –

Смежные вопросы