【问题标题】:Bootstrap type ahead bind values with knockoutjs not workingBootstrap 类型提前绑定值与 knockoutjs 不起作用
【发布时间】:2013-01-21 08:11:30
【问题描述】:

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

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

我想提前使用引导类型,以便查看产品信息。 我找到了这个 Article,它为我提供了执行此操作的事件处理程序。

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

Uncaught TypeError: Object [object Object] has no method 'toLowerCase' bootstrap.js:1831 未捕获的类型错误:无法使用 'in' 运算符在 1 中搜索 'length'

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

{
"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。

任何建议将不胜感激。

HTML:

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

编辑:

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

【问题讨论】:

  • 你的 HTML 带有敲除绑定吗?看来你在某处有错误的数据类型。
  • 添加到编辑:

标签: twitter-bootstrap knockout.js


【解决方案1】:

看看你提供的链接,你的目标和来源是不是弄错了?

基本上,预输入插件似乎需要一个可用于自动完成建议的字符串值数组。向 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());
        });
        return searchableTerms;
    });
};

然后将 html 更新为:

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

【讨论】:

  • 如果我切换它们,输入框会被 [object Object] 填充。在控制台中也收到此错误:***Uncaught TypeError: Cannot call method 'toLowerCase' of undefined bootstrap.js:1831 Typeahead.matcher bootstrap.js:1831 (anonymous function) bootstrap.js:1818 jQuery.extend.grep jquery -1.9.0.js:736 Typeahead.process bootstrap.js:1817 Typeahead.lookup bootstrap.js:1811 Typeahead.keyup bootstrap.js:1971 代理 jquery-1.9.0.js:801 jQuery.event.dispatch jquery-1.9 .0.js:3045 elemData.handle****
  • 它将被对象填充,因为你已经将它绑定到你的视图模型,这是一个对象。您需要添加一个计算的 observable,它返回您希望可搜索的三个字段中的文本。我会更新我的答案以表明我的意思。
  • 在实施建议的修复时出现此错误。 ****未捕获的错误:无法解析绑定。消息:ReferenceError:未定义 SearchText;绑定值:预先输入:{目标:产品,来源:SearchText} knockout-2.2.1.js:5**** 我将更新我的问题以反映我的整个 ViewModel 和 Ajax 调用。会不会是 Element 是在 Knockout Model 之前创建的?
  • 啊,那是因为您正在绑定到没有 SearchText 属性的 Products 视图模型。我会考虑如何在你的 typeahead 方法中遍历数组。
  • 查看更新的代码。这应该会提供您现在自动完成所需的文本。
猜你喜欢
  • 1970-01-01
  • 2013-01-03
  • 2015-12-19
  • 1970-01-01
  • 2016-01-10
  • 2017-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多