1

這是我用BootStrap typeahead字段編寫的敲除程序的自定義綁定。 一切都按預期工作,但我遇到的唯一問題是,每當我清楚我的場淘汰賽觀察到的仍包含最後一個有效selection.Not知道我做錯了..用引導程序自定義敲除綁定帶空值的Typeahead問題

ko.bindingHandlers.productTypeahead = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) 
     { 
     var root = bindingContext.$root; 

     var options = ko.unwrap(valueAccessor()) || {}, 
       $el = $(element); 

     options.source = _.debounce(function (query, process) { 
      root.api.SearchProducts(query) 
        .done(function (data) { 
         process(data); 
        }).fail(function (xhr) { 
         root._alert.error("Could not search products - " + JSON.parse(xhr.responseText).ExceptionMessage); 
        }); 
       } , 300); 

     $el.attr("autocomplete", "off") 
      .typeahead({ 
       source: options.source, 
       autoSelect: true, 
       displayText: function (item) { return item != null ? item.id : ""; }, 
       matcher: function() { return true; },// api does this already 
       items: 15, 
       minLength: 3, 
       updater: function (item) { 
        options.value(item); 
       }, 
       highlighter: function (item) { 
        var query = this.query; 
        query = query.replace(/[^\w\']+/g, "|"); 
        var queryRegex = new RegExp("\\b(" + query + ")", "gi"); 
        return item.replace(queryRegex, "<strong>$1</strong>"); 
       } 
      }); 

     // if KO removes the element via templating, then destroy the typeahead 
     ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
      $el.typeahead("destroy"); 
      $el = null; 
     }); 
    } 
}; 

回答

2

你可以使用input事件來處理這種情況。下面的代碼只檢查value === "",您可能會發現智能檢查在您的應用程序中效果更好。

另請注意,更改後的錯誤處理程序 - 如果沒有try/catch塊,您永遠不應解析JSON。

ko.bindingHandlers.productTypeahead = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var root = bindingContext.$root; 
     var options = ko.unwrap(valueAccessor()) || {}; 

     options.source = _.debounce(function (query, process) { 
      root.api.SearchProducts(query) 
       .done(process).fail(function (xhr) { 
        var responseData; 
        try { 
         responseData = JSON.parse(xhr.responseText); 
         root._alert.error("Could not search products - " + responseData.ExceptionMessage); 
        } catch (ex) { 
         root._alert.error("Unexpected response: " + xhr.responseText); 
        } 
       }); 
     } , 300); 

     $(element).attr("autocomplete", "off") 
      .typeahead({ 
       source: options.source, 
       autoSelect: true, 
       displayText: function (item) { return item !== null ? item.id : ""; }, 
       matcher: function() { return true; },// api does this already 
       items: 15, 
       minLength: 3, 
       // you can use observables as callbacks directly 
       updater: options.value, 
       highlighter: function (item) { 
        var query = this.query.replace(/[^\w']+/g, "|"); 
        var queryRegex = new RegExp("\\b(" + query + ")", "gi"); 
        return item.replace(queryRegex, "<strong>$1</strong>"); 
       } 
      }).on("input", function() { 
       if (this.value === "") { 
        options.value(""); 
       } 
      }); 

     // if KO removes the element via templating, then destroy the typeahead 
     ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
      $(element).typeahead("destroy"); 
     }); 
    } 
};