2017-01-11 5 views
0

Я пытаюсь создать привязку нокаута для Flatpickr, но не повезло. Я пробовал настроить код из принятого ответа here безрезультатно. Flatpickr инициализирован, но, похоже, он не использует параметры по умолчанию, которые у меня установлены, и часть обновления привязки просто не работает.Custom Flatpickr Knockout binding

Мой код ниже. Я хотел бы создать jsFiddle, но он заблокирован здесь на работе ..

ko.bindingHandlers.datetimepicker = { 
    init: function (element, valueAccessor, allBindingsAccessor) { 
    var options = allBindingsAccessor().datetimepickerOptions || { dateFormat: 'm-d-Y', enableTime: true }; 
    var $el = $(element); 

    $(element).flatpickr(options); 

    //handle the field changing by registering datepicker's changeDate event 
    ko.utils.registerEventHandler(element, "onChange", function() { 
     var observable = valueAccessor(); 
     observable($el.val()); 
    }); 

    //handle disposal (if KO removes by the template binding) 
    ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
     $el.flatpickr("destroy"); 
    }); 

    $el.val(new Date(ko.utils.unwrapObservable(valueAccessor()))); 
    }, 
    update: function (element, valueAccessor, allBindingsAccessor) { 
    var value = ko.utils.unwrapObservable(valueAccessor()); 
    var $el = $(element); 

    // handle json date from microsoft 
    if (String(value).indexOf('/Date(') == 0) { 
     value = new Date(parseInt(value.replace(/\/Date\((.*?)\)\//gi, "$1"))); 
    } 

    var current = new Date($el.val()); 

    if (value - current !== 0) { 
     $el.flatpickr('setDate', value); 
    } 
    } 
}; 

EDIT

Немного подробнее о моей ситуации. У меня есть страница с кнопками пейджера вверху, и эти кнопки циклически перемещаются по массиву в моей модели просмотра. Каждый раз, когда я просматриваю страницу, отображаемое свойство Record устанавливается в следующий/предыдущий элемент в массиве, и все поля редактирования привязаны к отображаемому свойству Record. Это отлично работает для всех моих входов, кроме тех, которые используют привязку datetimepicker, предоставленную мне @atitsbest.

Поля заполнения datetimepicker заполняются в первый раз, но после того, как я просматриваю их, свойство viewmodel для этой записи каким-то образом получает значение null.

EDIT 2

получил эту работу, наконец. Вот конечный продукт. Закончилось удаление подписки в функции init, потому что это вызвало ошибки при попытке установить, что она имеет значение NULL. Также добавлена ​​flatpickr функциональности обертки для пользователя, чтобы обеспечить свои собственные кнопки для очистки, переключая и т.д.

ko.bindingHandlers.flatpickr = { 
    init: function (element, valueAccessor, allBindingsAccessor) { 
    var options = $.extend({ 
     dateFormat: 'm/d/Y H:i', 
     enableTime: true, 
     time_24hr: true, 
     minuteIncrement: 1 
    }, allBindingsAccessor().flatpickrOptions); 
    var $el = $(element); 
    var picker; 

    if (options.wrap) { 
     picker = new Flatpickr(element.parentNode, options); 
    } else { 
     picker = new Flatpickr(element, options); 
    } 

    // Save instance for update method. 
    $el.data('datetimepickr_inst', picker); 

    // handle the field changing by registering datepicker's changeDate event 
    ko.utils.registerEventHandler(element, "change", function() { 
     valueAccessor()(picker.parseDate($el.val())); 
    }); 

    // handle disposal (if KO removes by the template binding) 
    ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
     $el.flatpickr("destroy"); 
    }); 
    }, 
    update: function (element, valueAccessor, allBindingsAccessor) { 
    // Get datepickr instance. 
    var picker = $(element).data('datetimepickr_inst'); 

    picker.setDate(ko.unwrap(valueAccessor())); 
    } 
}; 

ответ

1

Я создал jsfiddle и внес некоторые изменения в переплете

  • измененного название событие из «OnChange " изменить"; теперь он стреляет.
  • создал некоторые параметры по умолчанию, даже если установлены настраиваемые параметры; полезно по умолчанию dateFormat.
  • заменил функцию «обновление» подпиской на обновление наблюдаемого ;.
  • связанное значение теперь всегда является датой.

Новое связывание:

ko.bindingHandlers.datetimepicker = { 
    init: function(element, valueAccessor, allBindingsAccessor) { 
    var options = $.extend({ 
     dateFormat: 'm-d-Y H:i', 
     enableTime: true 
     }, allBindingsAccessor().datetimepickerOptions), 
     $el = $(element), 
     picker = new Flatpickr(element, options), 
     observable = valueAccessor(); 

    //handle the field changing by registering datepicker's changeDate event 
    ko.utils.registerEventHandler(element, "change", function() { 
     observable(picker.parseDate($el.val())); 
    }); 

    //handle disposal (if KO removes by the template binding) 
    ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
     $el.flatpickr("destroy"); 
    }); 

    observable.subscribe(function(newVal) { 
     $el.val(picker.formatDate(options.dateFormat, newVal)); 
    }); 

    picker.setDate(ko.unwrap(observable)); 
    } 
}; 

Надежда, что помогает.

UPDATE

Чтобы справиться с подкачкой я изменил переплета. Ниже приведено обновление jsfiddle для проверки привязки с помощью сценария поискового вызова. А вот новый связыванию код:

ko.bindingHandlers.datetimepicker = { 
    init: function(element, valueAccessor, allBindingsAccessor) { 
    var options = $.extend({ 
      dateFormat: 'm-d-Y H:i', 
      enableTime: true 
     }, 
     allBindingsAccessor().datetimepickerOptions), 
     $el = $(element), 
     picker = new Flatpickr(element, options); 

    // Save instance for update method. 
    $el.data('datetimepickr_inst', picker); 

    // handle the field changing by registering datepicker's changeDate event 
    ko.utils.registerEventHandler(element, "change", function() { 
     valueAccessor()(picker.parseDate($el.val())); 
    }); 

    // handle disposal (if KO removes by the template binding) 
    ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
     $el.flatpickr("destroy"); 
    }); 

    // Update datepicker with new value from observable 
    valueAccessor().subscribe(newVal => $el.val(picker.formatDate(options.dateFormat, newVal))); 
    }, 
    update: function(element, valueAccessor, allBindingsAccessor) { 
    // Get datepickr instance. 
    var picker = $(element).data('datetimepickr_inst'); 

    picker.setDate(ko.unwrap(valueAccessor())); 
    } 
}; 

Надежда, что помогает.

+0

Должен ли он иметь член обновления тоже? – JB06

+0

Это, кажется, не работает для меня, я думал, что это произошло сначала. См. Мое редактирование для почему и немного более подробно о моей проблеме. – JB06

+0

Должен ли он иметь член обновления?Вот что говорит документ: «Примечание: на самом деле вам не нужно предоставлять обратные вызовы init и update - вы можете просто предоставить тот или иной, если это все, что вам нужно». – atitsbest