Knockout 3+如何绑定jquery移动单选按钮进行淘汰?

时间:2017-05-02 04:29:15

标签: jquery-mobile knockout.js knockout-3.0

https://jsfiddle.net/9L8r9etf/2/

我一直在尝试一些不同的方法,但这是我最接近的方法。由于某种原因,this.checked总是如此。

的javascript:

ko.bindingHandlers.jqmChecked = {
    init: function (element, valueAccessor) {
        ko.utils.unwrapObservable(valueAccessor()); // This hack for knockout v3
        // set the dom element to a checkbox and initialize it (for jquerymobile)
        var checkbox = $(element);
        // let jquerymobile enhance the element
        checkbox.removeAttr('data-role');
        // make it so
        checkbox.checkboxradio();
        //register change event to update the model on changes to the dom
        checkbox.on('change', function (e) {
                if(this.checked)
            valueAccessor()(this.value);
        });
    },
    update: function (element, valueAccessor) {
        // update the checked binding, important for correct radio button behaviour.
        //ko.bindingHandlers.checked.update(element, valueAccessor);
        //ko.utils.unwrapObservable(valueAccessor()); // This hack for knockout v3

        // and refresh the element (for jquerymobile)
        var checkbox = $(element);
        checkbox.checkboxradio('refresh');
        checkbox.prop("checked", valueAccessor()()).checkboxradio("refresh");

    }
};

var ViewModel = function(repeat) {
        var self = this;
        self.testa = ko.observable(true);
    self.test = ko.observable("dyn");
    if(repeat){
    self.subView = ko.observable(new ViewModel(false));
    }
};

ko.applyBindings(new ViewModel(true));

HTML:

<fieldset data-role="controlgroup" data-mini="true" data-type="horizontal">
  <label><input type="radio" value="inp" name="inpdynout2" checked data-bind="jqmChecked:test"/> inp</label>
  <label><input type="radio" value="dyn" name="inpdynout2" data-bind="jqmChecked:test" /> dyn</label>
  <label><input type="radio" value="out" name="inpdynout2" data-bind="jqmChecked:test" /> out</label>
</fieldset>
<hr/>
x <span data-bind="text:test"></span><br/>

我理解在淘汰赛3中,你需要创建自己的事件监听器,而不是使用checked.update,但是我还没有弄清楚如何将它与原始检查绑定一起使用。

我希望绑定尽可能多地像淘汰3香草绑定一样,因为我们已经被自定义绑定未完成的错误所困扰。

2 个答案:

答案 0 :(得分:1)

如果您可以分享一些有关您在问题中提到的错误的详细信息,那将是很好的。无论如何,为了保持被检查的attr同步,我会使用这样的东西:

ko.bindingHandlers.jqmRadio = {
  init: function(element, valueAccessor, allBindings) {
    var value = valueAccessor(),
      valueUnwrapped = ko.unwrap(value);
    if (!valueUnwrapped) {
      var checkedValue = $('input[name=' + element.name + ']:checked').val();
      value(checkedValue);
    }
    return ko.bindingHandlers.checked.init.apply(this, arguments);
  },
  update: function(element, valueAccessor, allBindings) {
    var valueUnwrapped = ko.unwrap(valueAccessor()); // for dependency
    if (!!$.data(element, "mobile-checkboxradio")) {
      (element.value !== valueUnwrapped) ? $(element).removeAttr("checked"): $(element).attr("checked", "checked");
      $(element).checkboxradio("refresh");
    }
  }
};

var ViewModel = function() {
  var self = this;
  self.test = ko.observable(); // initialized by attr
  self.test2 = ko.observable("dyn"); // initialized by ko
};

$(document).ready(function() {
  ko.options.deferUpdates = true;
  ko.applyBindings(new ViewModel());
});
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
  <link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css">
  <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
  <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
</head>

<body>
  <div data-role="page">
    <div role="main" class="ui-content">
      <fieldset data-role="controlgroup" data-mini="true" data-type="horizontal">
        <label>
          <input type="radio" name="inpdynout" checked data-bind="checkedValue:'inp', jqmRadio:test"> inp</label>
        <label>
          <input type="radio" name="inpdynout" data-bind="checkedValue:'dyn', jqmRadio:test"> dyn</label>
        <label>
          <input type="radio" name="inpdynout" data-bind="checkedValue:'out', jqmRadio:test"> out</label>
      </fieldset>
      <hr/>
      <br/>
      <fieldset data-role="controlgroup" data-mini="true" data-type="horizontal">
        <label>
          <input type="radio" name="inpdynout2" data-bind="checkedValue:'inp', jqmRadio:test2"> inp</label>
        <label>
          <input type="radio" name="inpdynout2" data-bind="checkedValue:'dyn', jqmRadio:test2"> dyn</label>
        <label>
          <input type="radio" name="inpdynout2" data-bind="checkedValue:'out', jqmRadio:test2"> out</label>
      </fieldset>
      <hr/>
      <pre data-bind="text:ko.toJSON($data)"></pre>
    </div>

  </div>
</body>

</html>

答案 1 :(得分:-1)

ko.bindingHandlers.jqmCheckedRadio = {
    init: function (element, valueAccessor) {
        // set the dom element to a checkbox and initialize it (for jquerymobile)
        var checkbox = $(element);
        // let jquerymobile enhance the element
        checkbox.removeAttr('data-role');
        // make it so
        checkbox.checkboxradio();

        checkbox.on('change', function (e) {
            if ($(this).prop( "checked")) {//this is returning true always.
                valueAccessor()(this.value);
            }
        });
    },
    update: function (element, valueAccessor) {
        // update the checked binding, i.e., check or uncheck the checkbox
        var unwrapped = ko.utils.unwrapObservable(valueAccessor()); 
        // and refresh the element (for jquerymobile)
        $(element).prop("checked", element.value === unwrapped).checkboxradio("refresh");
    }
};

这适用于多个单选按钮的敲除3语义绑定到单个observable,但使用其属性值而不是checkValue。

尚未针对复选框或布尔单选按钮进行测试。

如果您需要动态数量的无线电按钮,它也可以正常工作。