2

我有一个非常简单的用于 Knockout.js 的 Bootstrap Typeahead 绑定(jsFiddle),如下所示:

ko.bindingHandlers.typeahead = {
    init: function (element, valueAccessor) {
        var $e = $(element),
            source = valueAccessor();

        $e.typeahead({
            source: source,
            minLength: 0
        });
    },
};

它的用法很简单:

<input data-bind='typeahead: source, value: item,
                  valueUpdate: "afterkeydown"' />

绑定在jsFiddle中按预期工作。但是,当使用 RequireJS 加载时,它并不总是按预期工作。似乎存在竞争条件,因为 Knockout 和 jQuery 正在并行加载。

如果我查看change绑定输入元素的事件处理程序,如果 jQuery 是处理程序,则绑定按预期工作。如果 Knockout 是change事件的处理程序,则例如,如果您键入“alp”,并且 Typeahead 建议“Alpha”,并且您从 Typeahead 下拉列表中选择“Alpha”,则<input>元素将显示所选文本(“Alpha” ),但绑定的 observable 将是“alp”。

在当前系统中,Typeahead 绑定不能直接修改给定的 observables,因此传递{ source: src, observable: item }不会解决问题。这个 Typeahead 绑定的作用只是更新绑定的输入区域的内容。

我已经尝试从绑定中触发相关事件,例如“keydown”、“keypress”和“keyup”,但由于显而易见的原因,这不是一个非常有弹性的选项。

我怀疑这个问题与 RequireJS 的不确定性有关,Typeahead 插件的工作与否取决于首先加载的是 jQuery 还是 Knockout。特别是,似乎通过使用 RequireJS 使 jQuery 成为 Knockout 的依赖项(即首先加载 jQuery)解决了这个问题shim

requirejs.config({
   shim: {
      knockout: { deps: ['jquery'] },
   }
 });

这看起来很奇怪,我想更好地了解这里发生的事情以及这是否是问题的合理解决方案——即我实际上是在解决这里的潜在问题,还是这个问题会随着后续版本的 Knockout 或 jQuery 而出现。

我会很感激任何想法。

编辑

您可以通过按顺序内联加载脚本来简单地复制问题,例如:

<script src='knockout.js'></script>
<script src='jquery.js'></script>

这是一个展示该问题的jsFiddle。

按上述顺序插件将失败;否则它将按预期工作。

无论如何,RequireJS 配置是这样的:

requirejs.config({
  baseUrl: "/script",
  shim: {
    knockout: { deps: ['jquery'] }, # remove this for race condition
  }
});

mainhas的简化版本require(['jquery', 'knockout', 'bindings'], ...),其中bindings定义了 Knockout 处理程序。该bindings.js文件有效地以define(['knockout', 'jquery'], ...).

在这种情况下,虽然问题不是 RequireJS,而是脚本的顺序。

4

1 回答 1

0

我怀疑您以某种方式缺少依赖项。可能是引导程序。

在这里查看我的示例。你看看垫片配置是对的。 http://jsfiddle.net/jaques/sfvy9/2/

requirejs.config({
    shim: {
        'bootstrap': {
            deps: ['jquery'],
            exports: 'jQuery.fn.typeahead'  // we can't test for more than one object                   
        }
    }
});
于 2013-02-05T23:53:56.570 回答