2017-05-02 6 views
0

https://jsfiddle.net/9L8r9etf/2/ノックアウト3+ jqueryモバイルラジオボタンをノックアウトにバインドするにはどうすればよいですか?

私はいくつかの方法を試してきましたが、これは私が得た最も近いものです。何らかの理由で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バニラバインディングのように機能するようにしたいと思います。

答えて

1

あなたが質問で言及したバグに関するいくつかの詳細を分かち合うことができればうれしいです。

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>

+0

deferUpdatesを使用してかどうかの違いは何ですか:とにかく、同期attrに確認を保つために、私はこのようなものを使用しますか?私のアプリケーションの他のものに影響することはありませんか? (まだ入手可能なバージョンではありません) $ .data(element、 "mobile-checkboxradio")は何ですか? と $(要素).attr( "checked"、 "checked"); vs $(element).prop( "checked"、element.value === unwrapped) –

+0

質問に記載されているバグは、他人が作成したカスタムバインディングの内部的なものです。ドキュメントの中で、チェックボックスやラジオボタンのために働いていますが、テストの不足やバージョン間のセマンティクスの変更などのために、チェックボックスなどの作業が終わるだけです。 –

+0

@RyanTheLeach:1)deferUpdates;私は失敗に対してこれをテストしました。もしあなたがそれを使わなければ、単に行を省略してください。 2)$ .data(要素、 "mobile-checkboxradio"はJQMがすでにウィジェットを作成しているかどうかをテストすることで、 "checkboxradio is not instance"エラーを回避します)3)checked:あなたのサンプルコードでこれを使用しています。あなたはフォームデータを取得し、フォームデータをサブミット/ストアするので、attrを使用するとフォームデータはko checkedValueバインディングと一致します(propまたはnothingを使用しない場合は、検査要素をチェックアウトします)。 – deblocker

-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つのセマンティクスを単一の観測可能に結合しているノックアウト次のように動作しますが、checkValueとは対照的に、その属性値を使用しています。

チェックボックスやブール型ラジオボタンのテストは行われていません。

動的な量のラジオボタンが必要な場合は、そのラジオボタンもOKです。

関連する問題