1

我的页面的一部分正在使用 UI 敲除,并在该部分上调用 ApplyBindings:

HTML

<div id="example">
    <p data-bind="text: message"/>
    <i class="icon-information" title="some tooltip here"/>
</div>

JS

var model = createModel();
ko.applyBindings(model, $("#example")[0]);

并且我创建了一个小部件,该小部件在封面下也使用了 Knockout,我想将其连接到i标签以获得一个不错的工具提示。问题是因为 applyBindings 基本上在i标签上被调用了两次,所以存在错误。我知道在人为的示例中,我可以将i标签移出绑定所在的位置,但在实际代码中,这很简单,不可能。

我的问题是人们如何处理这些类型的情况?最简单的答案是将小部件更改为不使用 Knockout,但这很糟糕并且是很多额外的代码。

请不要只关注上面的演示代码。这更像是一个理论上的例子。尝试使用真实示例将需要太多解释。

4

2 回答 2

2

我认为根据小部件的性质,您可以选择几个选项。

第一种是使用ko.applyBindingsToNodeAPI,而不是添加“数据绑定”属性并ko.applyBindings从您的小部件调用。

你会这样称呼它:

ko.applyBindingsToNode(element, { someBindings: val, anotherBinding: val2 });

它还接受第三个参数来传递数据上下文,用于控制流场景。

这是一个使用此 API 绑定单独的 observable 的示例,然后ko.applyBindings使用“正常”视图模型调用:http: //jsfiddle.net/rniemeyer/QBMSB/。当然可以以这种方式添加冲突的绑定(两个相同的绑定针对不同的值),因此可以有针对性地使用它。

如果您正在做一些更像是插入“模板”(一堆 HTML)并且调用ko.applyBindingsToNode每个元素不一定方便的事情,那么您可以使用此处描述的技术来防止将绑定应用于子元素。

因此,您将有一个简单的绑定,例如:

ko.bindingHandlers.stopBinding = {
    init: function() {
        return { controlsDescendantBindings: true };
    }
};

然后,您的小部件将插入一个包含此绑定的包装器元素。然后,您可以对孩子调用 applyBindings,而不必担心“正常”的 applyBindings 调用会干扰。

这是一个带有刚刚直接输入的小部件标记的示例:http: //jsfiddle.net/rniemeyer/Tf79p/。我的假设是您的小部件在调用时会添加这样的标记。

于 2013-06-01T01:39:56.973 回答
0

回复:上面的评论,它并没有打败拥有一个小部件的意义。

创建一个自定义绑定作为工具提示小部件和模型/视图模型之间的适配器(取决于您如何使用工具提示,或者您正在使用哪个工具提示小部件)。我以这种方式使用 jQuery 工具的工具提示(http://jquerytools.org/documentation/tooltip/index.html),只需要创建一个简单的自定义绑定处理程序:

ko.bindingHandlers.jqTooltip = {
  init: function (element, valueAccessor) {
     var options = valueAccessor() || {};
     $(element).tooltip();
  }
}

然后在您的绑定中:

data-bind="jqTooltip:{}"

或类似的东西,在对象中传递您需要的选项并调整自定义处理程序以正确接受这些选项(上面我没有这样做)。

这不应该采用单独的视图模型,并注意您的视图模型中可以有很多模型。使用 jqDialog、jqButton 等查看大量 Ryan Niemeyer 的示例(google it)。为了重用,将它作为一个单独的模型适当命名,并在需要时实例化。

于 2013-05-31T22:08:37.117 回答