【问题标题】:Twitter Typeahead, Knockout JS, and Twitter Bootstrap 3 not playing nicelyTwitter Typeahead、Knockout JS 和 Twitter Bootstrap 3 运行不佳
【发布时间】:2014-04-17 13:41:12
【问题描述】:

我正在尝试使用 Bootstrap 3 为 typeahead jQuery 获取 knockout-bootstrap 自定义绑定,以便我可以将它与 Durandal 2.0 一起使用,但它还不能正常工作。原始绑定如下:

koObject.bindingHandlers.typeahead = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var $element = $(element);
        var allBindings = allBindingsAccessor();
        var typeaheadOpts = { source: koObject.utils.unwrapObservable(valueAccessor()) };

        if (allBindings.typeaheadOptions) {
            $.each(allBindings.typeaheadOptions, function(optionName, optionValue) {
                typeaheadOpts[optionName] = koObject.utils.unwrapObservable(optionValue);
            });
        }

        $element.attr("autocomplete", "off").typeahead(typeaheadOpts);
    }
};

自 Bootstrap 3 以来,typeahead 是一个单独的插件,因此我需要进行一些更改。我已将绑定修改为如下所示:

koObject.bindingHandlers.typeahead = {
    init: function (element, valueAccessor, bindingAccessor) {
        var $e = $(element),
            options = koObject.utils.unwrapObservable(valueAccessor());

        console.dir(options.source());

        console.dir($e);

        // passing in `null` for the `options` arguments will result in the default
        // options being used
        $e.typeahead({ 
            highlight: true,
            minLength: 2,           
        },
        {             
            source: options.source()
        }).on('typeahead:selected', function (el, datum) {
            console.dir(datum);
        }).on('typeahead:autocompleted', function (el, datum) {
            console.dir(datum);
        });

    }
};

我已经简化了敲除引导示例 HTML 以仅演示 typeahead 绑定。我遇到的问题是,当 typeahead 尝试提供建议时,它会在 1184 线上中断并抛出 Uncaught TypeError: object is not a function 异常。我试图为此创建一个jsFiddle,但它目前不起作用。

我缺少什么来获得 Twitter typeahead 0.10.2 jQuery、knockout 3.1.0、Bootstrap 3.1.1 和 Durandal 2.0?

【问题讨论】:

  • 您使用的是哪个版本的预输入?从 bootstrap 3 开始,typeahead.js 现在不是 bootstrap 的一部分,因此如果您使用 twitter typeahead.js,您需要使用不同的自定义绑定。这还取决于您是否使用 Bloodhound.js。这是带有 Bloodhound 的 knockout.js 和 typeahead.js 的工作示例 - stackoverflow.com/questions/22055808/…
  • 我正在使用 Twitter typeahead 0.10.2、knockout 3.1.0 和 Bootstrap 3.1.1。我没有使用 Bloodhound.js,因为我将使用自己的建议引擎。我会看看你链接的答案。
  • 如果有办法建议以输入的前几个字符开头的项目,我会使用 Bloodhound。否则,我将推出自己的建议功能来搜索 ko.observableArray 的开头。

标签: jquery twitter-bootstrap knockout.js durandal-2.0 twitter-typeahead


【解决方案1】:

Here is an updated, working version of your fiddle.。我所做的只是使用substringMatcher 函数并将jsFrameworks 数组作为预输入源传递给它 - exactly how it is used in the typeahead.js first example

因此,当您启动 typeahead 时,绑定处理程序中的 source 选项变为:

source: substringMatcher(options.source())

其中options.source()jsFrameworks 可观察数组的底层数组。

这是完整的绑定处理程序

ko.bindingHandlers.typeahead = {
        init: function (element, valueAccessor, bindingAccessor) {
            var substringMatcher = function (strs) {
                return function findMatches(q, cb) {
                    var matches, substringRegex;

                    // an array that will be populated with substring matches
                    matches = [];

                    // regex used to determine if a string contains the substring `q`
                    substrRegex = new RegExp(q, 'i');

                    // iterate through the pool of strings and for any string that
                    // contains the substring `q`, add it to the `matches` array
                    $.each(strs, function (i, str) {
                        // console.log(str);
                        if (substrRegex.test(str)) {
                            // the typeahead jQuery plugin expects suggestions to a
                            // JavaScript object, refer to typeahead docs for more info
                            matches.push({
                                value: str
                            });
                        }
                    });

                    cb(matches);
                };
            };
            var $e = $(element),
                options = valueAccessor();

            console.dir(options.source());

            console.dir($e);

            // passing in `null` for the `options` arguments will result in the default
            // options being used
            $e.typeahead({
                highlight: true,
                minLength: 2
            }, {
                source: substringMatcher(options.source())
            }).on('typeahead:selected', function (el, datum) {
                console.dir(datum);
            }).on('typeahead:autocompleted', function (el, datum) {
                console.dir(datum);
            });

        }
    };

【讨论】:

  • 我想我不需要解开 valueAccessor。我仍在学习自定义绑定的工作原理,这很有帮助。谢谢!
  • @CameronTinker 不要引用我的话,但我很确定 valueAccessor 的展开是针对 Knockout 2.x 及更低版本的。从 3.0 及更高版本开始,您不再需要这样做了。
  • 我看到我忘记的主要事情是将源设为对象数组而不是字符串数组。很高兴知道不需要在 Knockout 3.x 中解开 observables。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-04
  • 2013-07-20
  • 2016-04-03
  • 2012-09-05
  • 2013-09-10
  • 1970-01-01
相关资源
最近更新 更多