Bootstrap类型提前绑定与knockout.js的值不起作用 [英] Bootstrap type ahead bind values with knockoutjs not working

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

问题描述

我有一个用剔除创建的ViewModel,其中包含我产品的所有信息. 看起来像这样:

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:

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

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

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

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
    }
]
}

我只想搜索ProductSKUName,ProductSKUStockCode或ProductSKUManufactureStockCode.

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

任何建议将不胜感激.

HTML:

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

我的Javascript:

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?

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

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;
    });
};

然后将html更新为:

Then update the html to something like:

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

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

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