我的目标:使用KnockoutJS我有一组输入文本字段,用户可以输入他们的产品名称和typeahead.js将为每个文本框提供自动建议.可以动态添加或删除更多这些文本字段.
查看实例(JS Fiddle):http://jsfiddle.net/justosophy/5Z9We/
问题是:Typeahead适用于初始文本字段,但仅适用于动态字段.敲除自定义绑定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',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)); });
解决方法
您需要使新添加的项的属性也可观察.
最初的项目正在运行,因为在self.products中
self.products = ko.observableArray(ko.utils.arrayMap(products,productID: ko.observable(product.productID) }; }));
您已创建具有可观察属性的项目.
因此,将addProduct函数更改为:
self.addProduct = function () { self.products.push({ productName: ko.observable(""),productID: ko.observable(0) }); };