Knockout - 我可以将DOM属性绑定到observable吗?

时间:2015-11-30 10:30:45

标签: knockout.js

我想为我的observable使用特定div的height属性。 div的高度可能因非模型相关原因而改变:假设我是否通过Firebug添加内容。我想让模型跟踪新值。

我尝试过使用计算的observable,但这只是在实例化时使用第一个值(这与我在文档中读到的一样正常)。

model.divHeight = ko.computed({
    read: function(){return $("#specialDiv").height());},
    owner: model
});

我怎样才能做到这一点?

请注意,我要求高度,但这对于所有dom节点属性都是可扩展的,例如宽度,字体大小,颜色等。就像Firebug如何使用“Computed”属性选项卡一样。

2 个答案:

答案 0 :(得分:3)

下面是一个示例以及使用轮询的绑定处理程序。

检测高度变化的非轮询解决方案的替代方案是this answer(非轮询插件can be found here - 并且最好在绑定处理程序中使用)

轮询示例:

model.divHeight = ko.observable($("#element").height());
window.setInterval(function(){
  if( $("#element").height() != model.divHeight() )
      {
          model.divHeight($("#element").height());
      }
}, 50);

作为自定义绑定处理程序的示例 - 使用轮询:

ko.bindingHandlers.checkElementHeight = {
  init: function(element, valueAccessor) {
    var value = valueAccessor();
    window.setInterval(function(){
      if( $(element).height() != value() )
        {
          value($(element).height());
        }
      }, 50);
    }
 };

答案 1 :(得分:0)

编辑:在Bogdan Goie的回答版本之前,这个答案更有意义。现在,它只是指向ko自定义绑定的文档,以及另一种非轮询属性更改选项。 Bogdan Goie的回答非常完美。我只保留这个额外的链接和替代品。

此用例的正确实现是custom binding

自定义绑定的实现是:

lib

在您的情况下,在ko.bindingHandlers.yourBindingName = { init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { // This will be called when the binding is first applied to an element // Set up any initial state, event handlers, etc. here }, update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { // This will be called once when the binding is first applied to an element, // and again whenever any observables/computeds that are accessed change // Update the DOM element based on the supplied values here. } }; 函数中,您必须使用检测元素init更改的代码。在更新中,您必须做相反的事情:您收到新的可观察值,并且必须使用它来更新元素的height

您可以使用此解决方案代替其他答案的轮询解决方案:Cross-Browser, Event-based, Element Resize Detection代码如下:

height