试图控制后代绑定的选项和组件

时间:2015-08-10 17:34:59

标签: knockout.js

在下面的小提琴中,我试图根据正在迭代的数据中的字段渲染几个组件之一。我已经定义了这些模板:

<template id="select-template">
    <select data-bind="style: {width: size}, value: value, options: options, optionsText: 'optTxt', optionsValue: 'optId'"></select>
</template>
<template id="input-template">
    <!--input type="text" data-bind="style: {width: size}, value: value" /-->
    <input type="text" data-bind="value: 'input'" />
</template>
<template id="mu-template">
    <span data-bind="text: value"></span>
</template>

并注册了这些相应的组件:

ko.components.register('input', {
    viewModel: InputModel,
    template: {
        element: 'input-template'
    }
});
ko.components.register('select', {
    viewModel: InputModel,
    template: {
        element: 'select-template'
    }
});
ko.components.register('mu', {
    viewModel: InputModel,
    template: {
        element: 'mu-template'
    }
});

他们都使用的viewmodel构造函数是:

function InputModel(params) {
    if (!('id' in params)) {
        throw "Model broke";
    }
    var keys = ['id', 'size', 'value', 'options'];
    for (var i=0; i<keys.length; ++i) {
        var k = keys[i];
        if (k in params) {
            this[k] = params[k];
        }
    }
    console.debug("Model:", [this]);
}

我有两个问题:

  1. 当呈现选择模板时,我收到错误消息 Multiple bindings (options and component) are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element.
  2. 可能相关,如果我没有在InputModel中进行错误检查/抛出,则会在没有参数的无限循环中调用它。
  3. 这里发生了什么?

    http://jsfiddle.net/6srq9yfc/

1 个答案:

答案 0 :(得分:2)

问题是您使用现有DOM元素的名称注册组件:inputselect

因此,KO试图绑定

<select data-bind="style: {width: size}, 
            value: value, options: options, 
            optionsText: 'optTxt', optionsValue: 'optId'"></select>`

作为组件options绑定发生冲突,您收到错误消息。

您可以通过将组件重命名为不存在的DOM元素来轻松解决此问题:

ko.components.register('my-input', {
    viewModel: InputModel,
    template: {
        element: 'input-template'
    }
});
ko.components.register('my-select', {
    viewModel: InputModel,
    template: {
        element: 'select-template'
    }
});

演示JSFiddle