我使用prettyCheckable jquery插件使我的复选框和单选按钮看起来很漂亮,如果我使用data-bind="checked: dateMode"它不起作用,因为插件隐藏了实际的复选框,并使它自己的覆盖html来美化复选框/单选框,因此knockoutjs库不识别当我检查单选框或复选框并更新模型中的值。我知道我的代码工作良好,如果我不使用prettyCheckable插件,所以不要告诉我我的模型或数据绑定代码是混乱的。我测试了一下。
https://github.com/arthurgouveia/prettyCheckable这是我的部分视图代码。
<div id="DatesChooser" class="span5 pull-left">
<h4><i class="icon-calendar"></i>Dates</h4>
<input type="radio" name="Date" value="All" data-label="All Available" data-bind="checked: dateMode" /><br />
<input type="radio" name="Date" value="Range" data-label="Range" data-bind="checked: dateMode" />
<div data-bind="visible: dateMode() == 'Range'">
<input type="text" id="FromYear" placeholder="1970" /> to
<input type="text" id="ToYear" placeholder="2012" /><br />
<div id="Date-Slider" class="ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all">
<div id="Date-Slider-Bar" class="ui-slider-range ui-widget-header" style="left: 0%; width: 100%;"></div>
<a class="ui-slider-handle ui-state-default ui-corner-all" href="#" style="left: 0%;"></a>
<a class="ui-slider-handle ui-state-default ui-corner-all" href="#" style="left: 100%;"></a>
</div>
</div>
</div>
这是我的淘汰模型:
function searchVm() {
var self = this;
self.dateMode = ko.observable("All");
self.startSearch = function () { alert(self.dateMode()); };
};
我像这样初始化prettyCheckable
$('input:checkbox').prettyCheckable();
$('input:radio').prettyCheckable();
下面是prettyCheckable插件修改后的代码呈现,注意输入样式是'display:none':
<div id="DatesChooser" class="span5 pull-left">
<div class="clearfix prettyradio labelright blue">
<input type="radio" data-bind="checked: dateMode" data-label="All Available" value="All" name="Date" style="display: none;" checked="checked">
<a class="checked" href="#"></a>
<label for="undefined">All Available</label>
</div>
<br>
<div class="clearfix prettyradio labelright blue">
<input type="radio" data-bind="checked: dateMode" data-label="Range" value="Range" name="Date" style="display: none;">
<a class="" href="#"></a>
<label for="undefined">Range</label>
</div>
<div data-bind="visible: dateMode() == 'Range'" style="display: none;">
<input id="FromYear" class="placeholder" type="text" placeholder="1970">
to
<input id="ToYear" class="placeholder" type="text" placeholder="2012">
<br>
<div id="Date-Slider" class="ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all">
<div id="Date-Slider-Bar" class="ui-slider-range ui-widget-header" style="left: 0%; width: 100%;"></div>
<a class="ui-slider-handle ui-state-default ui-corner-all" style="left: 0%;" href="#"></a>
<a class="ui-slider-handle ui-state-default ui-corner-all" style="left: 100%;" href="#"></a>
<div class="ui-slider-range ui-widget-header" style="left: 0%; width: 100%;"></div>
</div>
</div>
</div>
Pretty Checkable触发复选框上的change
事件,但Knockout查找click
事件。这可以通过prettyCheckable.js
行46-54的变化来修复。原:
if (input.attr('checked') !== undefined) {
input.removeAttr('checked').change();
} else {
input.attr('checked', 'checked').change();
}
改变:
if (window.ko) {
ko.utils.triggerEvent(input[0], 'click');
} else {
input.click();
}
Knockout也不会工作,如果你使用jQuery的click
触发器函数。你必须像上面那样使用Knockout的triggerEvent
。
jsFiddle: http://jsfiddle.net/mbest/4cX48/
这里没有任何问题。Pretty Checkable库就是这样工作的。
查找输入dom隐藏它们,并使用动态的a和label标签代替该输入。如果您想要发现输入是否被检查,您需要检查动态添加的标记类(class ="checked")。不是原来的输入标签
您需要为prettycheckable编写一个绑定,并观察a标记的类。然后根据标签的类别更改绑定的检查值。
http://knockoutjs.com/documentation/custom-bindings.html@Michael对prettyCheckbox 的修改大部分有效,但是如果你的viewModel在加载时已经有一个选择,prettyCheckbox将无法识别它,因为它正在寻找"checked" 属性而knockout/plain vanilla html将通过属性将复选框标记为checked。
in prettyCheckbox change:
var isChecked = el.attr('checked') !== undefined ? 'checked' : '';
var isChecked = el.prop('checked') == true ? 'checked' : '';
另外,重要的是要知道,如果你在代码中修改了你的knockout viewmodel属性,它将不会反映在prettyCheckbox中,因为我不知道一种方法来订阅(在javascript中,而不是knockout)属性的变化。