自定义挖空绑定不更新底层可观察对象

时间:2015-03-27 13:11:25

标签: knockout.js custom-binding

我有一个绑定到自定义绑定的文本框。为了一个例子的全部它,它用一个带边框的div包装控件。然后我将绑定的observable传递给值绑定,但它没有像我期望的那样更新底层的observable。

= HTML =

  <body data-bind="with: model">
    <textarea data-bind="wrapbox: someval" ></textarea>
    <textarea data-bind="value: someval" ></textarea>
    <div data-bind="text: someval"></div>
  </body>

=的js =

ko.bindingHandlers.wrapbox = {
  update: function(element, valueAccessor)
  {
    var value = ko.unwrap(valueAccessor());
    $(element).wrap("<div class='border' />");
    return ko.bindingHandlers.value.update(element, 
       function(){return value; });
    //return ko.bindingHandlers.value.update(element, 
    //   valueAccessor()); <---- tried this too.
  }
};  


var viewmodel = function() {
  var model = {};
    model.someval = ko.observable();

  return {
    model: ko.observable(model)
  };
}();

ko.applyBindings(viewmodel);

=实施例=

http://liveweave.com/QmJeaH

2 个答案:

答案 0 :(得分:1)

您的绑定处理程序应该

  • init
  • 中设置其状态
  • 直接将所有内容传递到valueinit
  • 中的update绑定

代码:

ko.bindingHandlers.wrapbox = {
  init: function (element, valueAccessor, allBindingsAccessor, 
                    viewModel, bindingContext) {
        $(element).wrap("<div class='border' />");
        ko.bindingHandlers.value.init(element, valueAccessor, 
             allBindingsAccessor, viewModel, bindingContext);
    },
    update: function (element, valueAccessor, allBindingsAccessor, 
                     viewModel, bindingContext) {
        ko.bindingHandlers.value.update(element, valueAccessor, 
             allBindingsAccessor, viewModel, bindingContext);
    }
};

更新了您的示例:http://liveweave.com/Yq1UPl

答案 1 :(得分:1)

确保在init处理程序中设置绑定,与update相比,只运行一次且应包含$.wrap

沿着这些方向,如果你包装另一个绑定,请确保在适当的时候调用它的initupdate,并传递它可能需要的所有参数:

ko.bindingHandlers.wrapbox = {
  init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    $(element).wrap("<div class='border' />");
    
    return ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
  },
  update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    return ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
  }
};

var viewmodel = function() {
  var model = {};
    model.someval = ko.observable('');
  
  return {
    model: ko.observable(model)
  };
}();

ko.applyBindings(viewmodel);
.lw { font-size: 60px; }

.border{
  border:  3px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<div data-bind="with: model">
    <textarea data-bind="wrapbox: someval" ></textarea>
    <textarea data-bind="value: someval" ></textarea>
    <div data-bind="text: someval"></div>
</div>