我有一个very simple Bootstrap Typeahead binding (jsFiddle)的Knockout.js,像这样:
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>
element将显示所选文本(“Alpha”),但绑定的observable将为“alp”。
在当前系统中,Typeahead绑定不能直接修改给定的observable,因此传递{ source: src, observable: item }
无法解决问题。此Typeahead绑定的作用仅是更新绑定输入区域的内容。
我已尝试从绑定中触发相关事件,例如'keydown','keypress'和'keyup',但由于显而易见的原因,这不是一个非常有弹性的选项。
我怀疑问题与RequireJS的不确定性有关,Typeahead插件的工作与否取决于jQuery或Knockout是否先加载。特别是,似乎通过使jQuery成为Knockout的依赖项(即首先加载jQuery)和RequireJS的shim
来解决这个问题:
requirejs.config({
shim: {
knockout: { deps: ['jquery'] },
}
});
这看起来很奇怪,我想更好地了解这里发生了什么,如果这是一个合理的问题解决方案 - 即我实际上是在解决这里的潜在问题,还是可以解决后续版本的Knockout问题或jQuery。
我会很感激任何想法。
修改
您可以通过内联加载脚本来简单地复制问题,例如:
<script src='knockout.js'></script>
<script src='jquery.js'></script>
这是jsFiddle exhibiting the issue.
按上述顺序,插件将失败;否则它将按预期工作。
在任何情况下,RequireJS配置都是这样的:
requirejs.config({
baseUrl: "/script",
shim: {
knockout: { deps: ['jquery'] }, # remove this for race condition
}
});
main
的简化版本有require(['jquery', 'knockout', 'bindings'], ...)
,其中bindings
定义了Knockout处理程序。 bindings.js
文件实际上以define(['knockout', 'jquery'], ...)
开头。
在这种情况下虽然问题不是RequireJS,而是脚本的排序。
答案 0 :(得分:0)
我怀疑你在某种程度上错过了依赖。可能是引导程序。
请看我的例子。你是正确的看看垫片配置。 http://jsfiddle.net/jaquers/sfvy9/2/
requirejs.config({
shim: {
'bootstrap': {
deps: ['jquery'],
exports: 'jQuery.fn.typeahead' // we can't test for more than one object
}
}
});