Bootstrap 类型提前绑定值,而knockoutjs 不起作用 [英] Bootstrap type ahead bind values with knockoutjs not working

查看:15
本文介绍了Bootstrap 类型提前绑定值,而knockoutjs 不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用淘汰赛创建的 ViewModel,其中包含我的产品的所有信息.它看起来像这样:

var ProductViewModelDS = 函数(数据){var self = this;self.ProductSKUID = ko.observable(data.ProductSKUID);self.ProductID = ko.observable(data.ProductID);self.ProductSKUStockCode = ko.observable(data.ProductSKUStockCode);self.ProductSKUManufacturePartNumber = ko.observable(data.ProductSKUManufacturePartNumber);self.ProductSKUName = ko.observable(data.ProductSKUName);self.ProductSKUPrice = ko.observable(data.ProductSKUPrice);self.ProductSKUSpecialPrice = ko.observable(data.ProductSKUSpecialPrice);self.ProductSKUIsOnSpecial = ko.observable(data.ProductSKUIsOnSpecial);self.ProductSKUMinimumOrderQty = ko.observable(data.ProductSKUMinimumOrderQty);self.ProductSKUMaximumOrderQty = ko.observable(data.ProductSKUMaximumOrderQty);self.ProductSKUCurrentStock = ko.observable(data.ProductSKUCurrentStock);}

我想提前使用引导程序类型,以便我可以查看产品信息.我发现这个 文章,它为我提供了执行此操作的事件处理程序.

但是一旦我开始输入,我的控制台就会出现这个错误:

未捕获的类型错误:对象 [object Object] 没有方法 'toLowerCase' bootstrap.js:1831未捕获的类型错误:无法使用 'in' 运算符在 1 中搜索 'length'

这是我从 AJAX 调用中获得的 JSON:

<代码>{d":[{"__type": "POS.Tracntrace.Member_Only.DAL.Models.CreateOrder.CreateOrderProductModel","ProductSKUID": 15,产品ID":1,"ProductSKUStockCode": "BPUNIRM1131","ProductSKUManufacturePartNumber": "600284403 1213","ProductSKUName": "DSD 1131 遥控器","ProductSKUPrice": 84,"ProductSKUSpecialPrice": null,"ProductSKUIsOnSpecial": "false","ProductSKUMMinimumOrderQty": 1,"ProductSKUMaximumOrderQty": 10000,ProductSKUCurrentStock":100},{"__type": "POS.Tracntrace.Member_Only.DAL.Models.CreateOrder.CreateOrderProductModel","ProductSKUID": 16,产品ID":2,"ProductSKUStockCode": "SDF213","ProductSKUManufacturePartNumber": "55511545121","ProductSKUName": "DSD 1132","ProductSKUPrice": 599,"ProductSKUSpecialPrice": null,"ProductSKUIsOnSpecial": "false","ProductSKUMMinimumOrderQty": 1,"ProductSKUMaximumOrderQty": 10000,ProductSKUCurrentStock":100},{"__type": "POS.Tracntrace.Member_Only.DAL.Models.CreateOrder.CreateOrderProductModel","ProductSKUID": 17,产品ID":3,"ProductSKUStockCode": "RPAIRDRHD","ProductSKUManufacturePartNumber": "600284400 1018","ProductSKUName": "高清 PVR 遥控器","ProductSKUPrice": 250,"ProductSKUSpecialPrice": null,"ProductSKUIsOnSpecial": "false","ProductSKUMMinimumOrderQty": 1,"ProductSKUMaximumOrderQty": 10000,ProductSKUCurrentStock":100},{"__type": "POS.Tracntrace.Member_Only.DAL.Models.CreateOrder.CreateOrderProductModel","ProductSKUID": 18,产品ID":4,"ProductSKUStockCode": "1131","ProductSKUManufacturePartNumber": "DSD1131","ProductSKUName": "DSD1131 DVB-S","ProductSKUPrice": 499,"ProductSKUSpecialPrice": 498,"ProductSKUIsOnSpecial": "false","ProductSKUMMinimumOrderQty": 1,"ProductSKUMaximumOrderQty": 10000,ProductSKUCurrentStock":100},{"__type": "POS.Tracntrace.Member_Only.DAL.Models.CreateOrder.CreateOrderProductModel","ProductSKUID": 19,产品ID":5,"ProductSKUStockCode": "4660","ProductSKUManufacturePartNumber": "DSR4660","ProductSKUName": "DSR4660 HD DVB-S2","ProductSKUPrice": 1499,"ProductSKUSpecialPrice": null,"ProductSKUIsOnSpecial": "false","ProductSKUMMinimumOrderQty": 1,"ProductSKUMaximumOrderQty": 100,ProductSKUCurrentStock":100},{"__type": "POS.Tracntrace.Member_Only.DAL.Models.CreateOrder.CreateOrderProductModel","ProductSKUID": 20,产品ID":6,"ProductSKUStockCode": "DVR3000","ProductSKUManufacturePartNumber": "MCSDPVR3000","ProductSKUName": "DVR3000","ProductSKUPrice": 1500,"ProductSKUSpecialPrice": null,"ProductSKUIsOnSpecial": "false","ProductSKUMMinimumOrderQty": 1,"ProductSKUMaximumOrderQty": 10000,ProductSKUCurrentStock":100},{"__type": "POS.Tracntrace.Member_Only.DAL.Models.CreateOrder.CreateOrderProductModel","ProductSKUID": 21,产品ID":7,"ProductSKUStockCode": "DE45","ProductSKUManufacturePartNumber": "N/A","ProductSKUName": "ELSAT 45CM 低碳钢盘","ProductSKUPrice": 560,"ProductSKUSpecialPrice": null,"ProductSKUIsOnSpecial": "false","ProductSKUMMinimumOrderQty": 1,"ProductSKUMaximumOrderQty": 10000,ProductSKUCurrentStock":100},{"__type": "POS.Tracntrace.Member_Only.DAL.Models.CreateOrder.CreateOrderProductModel","ProductSKUID": 22,产品ID":8,"ProductSKUStockCode": "DE60","ProductSKUManufacturePartNumber": "N/A","ProductSKUName": "ELSAT 60CM 低碳钢盘","ProductSKUPrice": 900,"ProductSKUSpecialPrice": null,"ProductSKUIsOnSpecial": "false","ProductSKUMMinimumOrderQty": 1,"ProductSKUMaximumOrderQty": 10000,ProductSKUCurrentStock":100}]}

我只想能够搜索 ProductSKUName、ProductSKUStockCode 或 ProductSKUManufactureStockCode.

任何建议将不胜感激.

HTML:

 

<input type="text" data-bind="typeahead: { target: ProductViewModel, source: Products }"/>

我的 JavaScript:

 ko.bindingHandlers.typeahead = {初始化:函数(元素,valueAccessor){var 绑定 = this;var elem = $(元素);var value = valueAccessor();elem.typeahead({来源:函数(){返回ko.utils.unwrapObservable(value.source);},onselect: 函数 (val) { value.target(val);}});elem.blur(function () { value.target(elem.val()); });},更新:函数(元素,valueAccessor){var elem = $(元素);var value = valueAccessor();elem.val(value.target());}};var ProductViewModelDS = 函数(数据){var self = this;self.ProductSKUID = ko.observable(data.ProductSKUID);self.ProductID = ko.observable(data.ProductID);self.ProductSKUStockCode = ko.observable(data.ProductSKUStockCode);self.ProductSKUManufacturePartNumber = ko.observable(data.ProductSKUManufacturePartNumber);self.ProductSKUName = ko.observable(data.ProductSKUName);self.ProductSKUPrice = ko.observable(data.ProductSKUPrice);self.ProductSKUSpecialPrice = ko.observable(data.ProductSKUSpecialPrice);self.ProductSKUIsOnSpecial = ko.observable(data.ProductSKUIsOnSpecial);self.ProductSKUMinimumOrderQty = ko.observable(data.ProductSKUMinimumOrderQty);self.ProductSKUMaximumOrderQty = ko.observable(data.ProductSKUMaximumOrderQty);self.ProductSKUCurrentStock = ko.observable(data.ProductSKUCurrentStock);self.SearchText = ko.computed(function () {return self.ProductSKUName() + ' ' + self.ProductSKUStockCode() + ' ' + self.ProductSKUManufacturePartNumber();});}var ProductViewModel = 函数(产品){var self = this;self.Products = ko.observableArray(Products);$.ajax({url: "CreateOrder.aspx/GetAvailibleProducts",数据: '{}',类型:POST",contentType: "application/json; charset=utf-8",数据类型:JSON",超时:10000,成功:功能(结果){var MappedProducts =$.map(Result.d,功能(项目){返回新的 ProductViewModelDS(item);});self.Products(MappedProducts);},错误:函数(xhr,状态){警报(状态+-"+xhr.responseText);}});self.Save = function () {alert('现在可以保存:' + ko.mapping.toJSON(self.Products));}};$(document).ready(function () {var VM = new ProductViewModel();ko.applyBindings(VM);})

解决方案

查看您提供的链接,您是不是找错了目标和来源?

基本上,类型提前插件似乎需要一个可用于自动完成建议的字符串值数组.向 ProductViewModel 添加 SearchText 属性,该属性循环遍历所有产品并将您想要的三个字段放入 searchterm 数组中.

var ProductViewModel = function () {self.SearchText = ko.computed(function(){var searchableTerms = [];ko.utils.arrayForEach(self.Products(), function (item){searchableTerms.push(item.ProductSKUName());searchableTerms.push(item.ProductSKUStockCode());searchableTerms.push(item.ProductSKUManufacturePartNumber());});返回 searchableTerms;});};

然后将 html 更新为类似:

<input type="text" data-bind="typeahead: { target: Products, source: SearchText }"/>

I have a ViewModel that I created with knockout which contains all the info for my product. And It looks like this:

var ProductViewModelDS = function (data) {
        var self = this;
        self.ProductSKUID = ko.observable(data.ProductSKUID);
        self.ProductID = ko.observable(data.ProductID);
        self.ProductSKUStockCode = ko.observable(data.ProductSKUStockCode);
        self.ProductSKUManufacturePartNumber = ko.observable(data.ProductSKUManufacturePartNumber);
        self.ProductSKUName = ko.observable(data.ProductSKUName);
        self.ProductSKUPrice = ko.observable(data.ProductSKUPrice);
        self.ProductSKUSpecialPrice = ko.observable(data.ProductSKUSpecialPrice);
        self.ProductSKUIsOnSpecial = ko.observable(data.ProductSKUIsOnSpecial);
        self.ProductSKUMinimumOrderQty = ko.observable(data.ProductSKUMinimumOrderQty);
        self.ProductSKUMaximumOrderQty = ko.observable(data.ProductSKUMaximumOrderQty);
        self.ProductSKUCurrentStock = ko.observable(data.ProductSKUCurrentStock);
    }

I want to use the bootstrap type ahead, so that i can view the product info. I found this Article which gives me the event handler to do this.

But as soon as I start typing I get this error in my console:

Uncaught TypeError: Object [object Object] has no method 'toLowerCase' bootstrap.js:1831 Uncaught TypeError: Cannot use 'in' operator to search for 'length' in 1

This is my JSON I get from my AJAX call:

{
"d": [
    {
        "__type": "POS.Tracntrace.Member_Only.DAL.Models.CreateOrder.CreateOrderProductModel",
        "ProductSKUID": 15,
        "ProductID": 1,
        "ProductSKUStockCode": "BPUNIRM1131",
        "ProductSKUManufacturePartNumber": "600284403 1213",
        "ProductSKUName": "DSD 1131 Remote Control",
        "ProductSKUPrice": 84,
        "ProductSKUSpecialPrice": null,
        "ProductSKUIsOnSpecial": "false",
        "ProductSKUMinimumOrderQty": 1,
        "ProductSKUMaximumOrderQty": 10000,
        "ProductSKUCurrentStock": 100
    },
    {
        "__type": "POS.Tracntrace.Member_Only.DAL.Models.CreateOrder.CreateOrderProductModel",
        "ProductSKUID": 16,
        "ProductID": 2,
        "ProductSKUStockCode": "SDF213",
        "ProductSKUManufacturePartNumber": "55511545121",
        "ProductSKUName": "DSD 1132",
        "ProductSKUPrice": 599,
        "ProductSKUSpecialPrice": null,
        "ProductSKUIsOnSpecial": "false",
        "ProductSKUMinimumOrderQty": 1,
        "ProductSKUMaximumOrderQty": 10000,
        "ProductSKUCurrentStock": 100
    },
    {
        "__type": "POS.Tracntrace.Member_Only.DAL.Models.CreateOrder.CreateOrderProductModel",
        "ProductSKUID": 17,
        "ProductID": 3,
        "ProductSKUStockCode": "RPAIRDRHD",
        "ProductSKUManufacturePartNumber": "600284400 1018",
        "ProductSKUName": "HD PVR Remote Control",
        "ProductSKUPrice": 250,
        "ProductSKUSpecialPrice": null,
        "ProductSKUIsOnSpecial": "false",
        "ProductSKUMinimumOrderQty": 1,
        "ProductSKUMaximumOrderQty": 10000,
        "ProductSKUCurrentStock": 100
    },
    {
        "__type": "POS.Tracntrace.Member_Only.DAL.Models.CreateOrder.CreateOrderProductModel",
        "ProductSKUID": 18,
        "ProductID": 4,
        "ProductSKUStockCode": "1131",
        "ProductSKUManufacturePartNumber": "DSD1131",
        "ProductSKUName": "DSD1131 DVB-S",
        "ProductSKUPrice": 499,
        "ProductSKUSpecialPrice": 498,
        "ProductSKUIsOnSpecial": "false",
        "ProductSKUMinimumOrderQty": 1,
        "ProductSKUMaximumOrderQty": 10000,
        "ProductSKUCurrentStock": 100
    },
    {
        "__type": "POS.Tracntrace.Member_Only.DAL.Models.CreateOrder.CreateOrderProductModel",
        "ProductSKUID": 19,
        "ProductID": 5,
        "ProductSKUStockCode": "4660",
        "ProductSKUManufacturePartNumber": "DSR4660",
        "ProductSKUName": "DSR4660 HD DVB-S2",
        "ProductSKUPrice": 1499,
        "ProductSKUSpecialPrice": null,
        "ProductSKUIsOnSpecial": "false",
        "ProductSKUMinimumOrderQty": 1,
        "ProductSKUMaximumOrderQty": 100,
        "ProductSKUCurrentStock": 100
    },
    {
        "__type": "POS.Tracntrace.Member_Only.DAL.Models.CreateOrder.CreateOrderProductModel",
        "ProductSKUID": 20,
        "ProductID": 6,
        "ProductSKUStockCode": "DVR3000",
        "ProductSKUManufacturePartNumber": "MCSDPVR3000",
        "ProductSKUName": "DVR3000",
        "ProductSKUPrice": 1500,
        "ProductSKUSpecialPrice": null,
        "ProductSKUIsOnSpecial": "false",
        "ProductSKUMinimumOrderQty": 1,
        "ProductSKUMaximumOrderQty": 10000,
        "ProductSKUCurrentStock": 100
    },
    {
        "__type": "POS.Tracntrace.Member_Only.DAL.Models.CreateOrder.CreateOrderProductModel",
        "ProductSKUID": 21,
        "ProductID": 7,
        "ProductSKUStockCode": "DE45",
        "ProductSKUManufacturePartNumber": "N/A",
        "ProductSKUName": "ELSAT 45CM MILD STEEL DISH",
        "ProductSKUPrice": 560,
        "ProductSKUSpecialPrice": null,
        "ProductSKUIsOnSpecial": "false",
        "ProductSKUMinimumOrderQty": 1,
        "ProductSKUMaximumOrderQty": 10000,
        "ProductSKUCurrentStock": 100
    },
    {
        "__type": "POS.Tracntrace.Member_Only.DAL.Models.CreateOrder.CreateOrderProductModel",
        "ProductSKUID": 22,
        "ProductID": 8,
        "ProductSKUStockCode": "DE60",
        "ProductSKUManufacturePartNumber": "N/A",
        "ProductSKUName": "ELSAT 60CM MILD STEEL DISH",
        "ProductSKUPrice": 900,
        "ProductSKUSpecialPrice": null,
        "ProductSKUIsOnSpecial": "false",
        "ProductSKUMinimumOrderQty": 1,
        "ProductSKUMaximumOrderQty": 10000,
        "ProductSKUCurrentStock": 100
    }
]
}

I just want to be able to search for ProductSKUName, ProductSKUStockCode or ProductSKUManufactureStockCode.

Any Advice will be greatly appreciated.

HTML:

    <div class="well">
    <input type="text" data-bind="typeahead: { target: ProductViewModel, source: Products }" />
</div>

Edit:

My Javascript:

        ko.bindingHandlers.typeahead = {
        init: function (element, valueAccessor) {
            var binding = this;
            var elem = $(element);
            var value = valueAccessor();
            elem.typeahead(
              {
                  source: function () { return ko.utils.unwrapObservable(value.source); },
                  onselect: function (val) { value.target(val); }
              });
            elem.blur(function () { value.target(elem.val()); });
        },
        update: function (element, valueAccessor) {
            var elem = $(element);
            var value = valueAccessor();
            elem.val(value.target());
        }
    };


    var ProductViewModelDS = function (data) {
        var self = this;
        self.ProductSKUID = ko.observable(data.ProductSKUID);
        self.ProductID = ko.observable(data.ProductID);
        self.ProductSKUStockCode = ko.observable(data.ProductSKUStockCode);
        self.ProductSKUManufacturePartNumber = ko.observable(data.ProductSKUManufacturePartNumber);
        self.ProductSKUName = ko.observable(data.ProductSKUName);
        self.ProductSKUPrice = ko.observable(data.ProductSKUPrice);
        self.ProductSKUSpecialPrice = ko.observable(data.ProductSKUSpecialPrice);
        self.ProductSKUIsOnSpecial = ko.observable(data.ProductSKUIsOnSpecial);
        self.ProductSKUMinimumOrderQty = ko.observable(data.ProductSKUMinimumOrderQty);
        self.ProductSKUMaximumOrderQty = ko.observable(data.ProductSKUMaximumOrderQty);
        self.ProductSKUCurrentStock = ko.observable(data.ProductSKUCurrentStock);
        self.SearchText = ko.computed(function () {
            return self.ProductSKUName() + ' ' + self.ProductSKUStockCode() + ' ' + self.ProductSKUManufacturePartNumber();
        });
    }

    var ProductViewModel = function (Products) {
        var self = this;

        self.Products = ko.observableArray(Products);

        $.ajax({
            url: "CreateOrder.aspx/GetAvailibleProducts",
            data: '{}',
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataType: "JSON",
            timeout: 10000,
            success: function (Result) {
                var MappedProducts =
              $.map(Result.d,
             function (item) {
                 return new ProductViewModelDS(item);
             }
               );
                self.Products(MappedProducts);
            },
            error: function (xhr, status) {
                alert(status + " - " + xhr.responseText);
            }
        });

        self.Save = function () {
            alert('Could Now Save: ' + ko.mapping.toJSON(self.Products));
        }
    };

    $(document).ready(function () {
        var VM = new ProductViewModel();
        ko.applyBindings(VM);
    })

解决方案

Looking at the link you provided, have you not got your target and source the wrong way round?

Basically, it appears that the type ahead plugin wants an array of string values it can use for the auto-complete suggestions. Add a SearchText property to the ProductViewModel that loops through all the products and puts the three fields you want into the searchterm array.

var ProductViewModel = function () {
    self.SearchText = ko.computed(function()
    {
        var searchableTerms = [];
        ko.utils.arrayForEach(self.Products(), function (item)
        {
            searchableTerms.push(item.ProductSKUName());
            searchableTerms.push(item.ProductSKUStockCode());
            searchableTerms.push(item.ProductSKUManufacturePartNumber());
        });
        return searchableTerms;
    });
};

Then update the html to something like:

<div class="well">
    <input type="text" data-bind="typeahead: { target: Products, source: SearchText }" />
</div>

这篇关于Bootstrap 类型提前绑定值,而knockoutjs 不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆