2013-07-18 7 views
7

私の目標: KnockoutJSの使用ユーザーが製品名に入力できる入力テキストフィールドのコレクションがあり、typeahead.jsは各テキストボックスに対して自動提案を行います。これらのテキストフィールドの多くは動的に追加または削除できます。knockoutJS typahead.jsのカスタムバインディングallBindingsAccessor関数を失う

は、実際の例(JSフィドル)を参照してください:http://jsfiddle.net/justosophy/5Z9We/

問題がある:先行入力された文字は、最初のテキストフィールドのために動作しますが、唯一の動的フィールドのために部分的に動作します。ノックアウトカスタムバインディングのallBindingsAccessor()は未定義であるため、値を保存することはできません。

エラー:

TypeError: string is not a function 

HTML:

<div data-bind="foreach: products"> 
    <div class="product"> 
     <label>Enter Product Name:</label> 
     <input type="text" class="text-input product-search" data-bind="typeahead: productName, value: productName, productNameVal: productName, productIDVal: productID, valueUpdate: 'afterkeydown'" /> 
     <a class="btn btn-danger" data-bind="click: $root.removeProduct" title="remove">remove</a> 
    </div> 
</div> 
<a class="btn btn-primary" data-bind="click: addProduct">Add another product</a> 

はJavaScript:

var my = {}, i; 
// Create two initial entry boxes 
my.initialData = []; 
for (i = 2; i !== 0; i -= 1) { 
    my.initialData.push({ productName: "", productID: 0 }); 
} 
// Knockout model 
my.ProductsModel = function (products) { 
    var self = this; 
    self.products = ko.observableArray(ko.utils.arrayMap(products, function (product) { 
     return { 
      productName: ko.observable(product.productName), 
      productID: ko.observable(product.productID) 
     }; 
    })); 
    self.addProduct = function() { 
     self.products.push({ 
      productName: "", 
      productID: 0 
     }); 
    }; 
    self.removeProduct = function (product) { 
     self.products.remove(product); 
    }; 
}; 
// List of product options 
my.productsList = [ 
    { value: 'alpha', productID: 1 }, 
    { value: 'apple', productID: 2 }, 
    { value: 'beta', productID: 3 }, 
    { value: 'bannana', productID: 4 }, 
    { value: 'gamma', productID: 5 }, 
    { value: 'grape', productID: 6 }, 
    { value: 'delta', productID: 7 }, 
    { value: 'dragonfruit',productID: 8 }, 
    { value: 'diamond',productID: 9 } 
]; 
// Typeahead handler 
ko.bindingHandlers.typeahead = { 
    init: function (element, valueAccessor, allBindingsAccessor) { 
     var $e = $(element), 
      productNameVal = allBindingsAccessor().productNameVal, 
      productIDVal = allBindingsAccessor().productIDVal; 

     var updateValues = function(datum) { 
      productNameVal(datum.value); 
      productIDVal(datum.productID); 
     }; 
     $e.typeahead({ 
      name: 'products', 
      local: my.productsList 
     }).on('typeahead:selected', function (el, datum) { 
      updateValues(datum); 
     }).on('typeahead:autocompleted', function (el, datum) { 
      updateValues(datum); 
     }).blur(function() { 
      var el, val, arrayCheck; 
      el = $(this); 
      val = el.val(); 
      arrayCheck = ($.grep(my.productsList, function (n) { return n.value === val; }).length !== 0); 
      if (!arrayCheck) { 
       el.val(''); 
       source(''); 
       productIDVal(0); 
      } 
     }); 
    } 
}; 
// Apply bindings 
$(document).ready(function() { 
    ko.applyBindings(new my.ProductsModel(my.initialData)); 
}); 

答えて

6

あなたはまた、観察新しく追加された項目のプロパティを確認する必要があります。

self.products

self.products = 
    ko.observableArray(ko.utils.arrayMap(products, function (product) { 
     return { 
      productName: ko.observable(product.productName), 
      productID: ko.observable(product.productID) 
     }; 
    })); 

にあなたが観測可能な特性を持つアイテムを作成しているので、最初の項目が働いています。

だからあなたaddProduct機能は、に変更します。

self.addProduct = function() { 
     self.products.push({ 
      productName: ko.observable(""), 
      productID: ko.observable(0) 
     }); 
    }; 

デモJSFiddle.

+0

パーフェクト感謝を! –

関連する問題