在 Internet Explorer 11 中给定错误绑定上下文的 Knockout 组件

Knockout component given incorrect binding context in Internet Explorer 11

我在 Internet Explorer 和 Chrome 中测试过一个错误,这只发生在 Internet Explorer 中。

我正在使用 Knockout-3.3.0Knockout Validation

我有一个使用类似于以下自定义元素的淘汰组件:

<div>

    ...

    <div data-bind="with: editableUser">
        <div data-bind="visible: !$parent.editMode">
            <user-picker params="value: $parent.user, multiple:false, hideSelection:true"></user-picker>
        </div>
    </div>

    ...

</div>

自定义元素是其他节点的后代,这些节点是我的视图模型的一部分,如上所示。

正在应用页面的脚本依赖项和视图模型绑定,如下所示:

<script src="/Scripts/knockout-3.3.0.debug.js"></script>
<script src="/Scripts/knockout.validation.js"></script>
<script src="/Scripts/CustomBindings.js"></script>

<script>
    $(function() {
        ko.validation.init({
            insertMessages: false,
            decorateInputElement: false,
            errorElementClass: "has-error has-feedback",
            decorateElementOnModified: true
        });
    });
</script>

<script src="/Scripts/UserPicker.js"></script>
<script src="/Scripts/UserModel.js"></script>
<script src="/Scripts/CustomComponents.js"></script>
<script type="text/javascript">
    var userModel;
    $(function() {
        var userRepository = new MyModule.UserRepository();
        userModel = new MyModule.UserModel(userRepository);
        ko.applyBindings(userModel);
    }); 
</script>

组件的模板在脚本之前的 MVC 部分中呈现;如下图:

<template id="user-picker-template">
    <div class="user-picker"> ... </div>
</template>

该组件已在 CustomComponents.js 中注册,如图所示。

ko.components.register('user-picker', {
    template: { element: 'user-picker-template' },
    viewModel: MyModule.UserPicker
});

我在 CustomBindings.js 文件中也有自定义的敲除绑定。

调试 Knockout 时,此函数中出现错误 applyBindingsToNodeInternal 这一行:

var initResult = handlerInitFn(node, getValueAccessor(bindingKey), allBindings, bindingContext['$data'], bindingContext);

ko.applyBindings 调用期间抛出 javascript 错误。

错误是user-picker-template里面的第一个binding中的属性是未定义的,这是因为使用的bindingContext不正确,userModel是被传递而不是 UserPicker.

由于错误,剩余的非组件相关绑定已完成,然后 user-picker 绑定随后正确完成,但由于 javascript 错误,我的点击事件中的一些回调代码没有没用。

在 Chrome 中调试时,忽略用户选择器的绑定,直到 userModel 被绑定。

有谁知道可能导致此错误的原因吗?

这是因为模板绑定在组件外部,直接在 <template> 元素内。 Knockout 没有专门跳过 <template> 元素,但 browsers that support <template> 报告的内容与普通元素不同。

解决此问题的最简单方法是不使用 <template> 而是使用 <script>:

<script type="text/html" id="user-picker-template">
    <div class="user-picker"> ... </div>
</script>