每当通过Knockout.JS更新DOM时,我都需要运行一个jquery ui位代码。我意识到这可以使用自定义绑定来完成,但这似乎与特定的视图模型有关,我想全局地这样做,所以每当它发生在它触发的任何viewmodel上时?
让我们说我总是希望在所有带有'needsdate'类的文本框上使用JQuery日期选择器,而不是将其添加到我的每个视图模型中,如果我可以在全局范围内完成它将会很棒。
这可能吗?
答案 0 :(得分:7)
如果您不打算动态添加/删除元素,那么您可以正常连接它们。但是,如果您正在使用动态内容(例如使用修改了其项目的observableArray),那么您有几个选项:
1-与答案here类似,您可以创建自定义绑定。如果您不想将值绑定到视图模型上的属性,则可以将绑定简化为:
ko.bindingHandlers.datepicker = {
init: function(element, valueAccessor) {
//initialize datepicker with some optional options
var options = ko.utils.unwrapObservable(valueAccessor());
$(element).datepicker(options);
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).datepicker("destroy");
});
}
};
您可以将它放在以下元素上:
<input data-bind="datepicker: { minDate: new Date() }" />
2-另一种选择是使用afterRender
的{{1}} functionality(和使用template
的{{1}})来连接你的日期选择器新内容呈现。
答案 1 :(得分:0)
我创建了一个refreshJQuery()
函数,可以一次性应用我所有的强健行为。然后,当我在视图模型中订阅observables以更新我的模型时,我调用此函数。一旦加载页面。
function refreshJQuery() {
$(".draggable, .droppable, .resizable").each(function () {
var $element = $(this);
if ($element.hasClass("draggable") && !$element.data("init-draggable")) {
$element.data("init-draggable", true).draggable(dragBehavior);
}
if ($element.hasClass("droppable") && !$element.data("init-droppable")) {
$element.data("init-droppable", true).droppable(dropBehavior);
}
if ($element.hasClass("resizable") && !$element.data("init-resizable")) {
$element.data("init-resizable", true).resizable(resizeBehavior);
$(this).children().fadeTo(2000, 0);
$element.hover(function () {
$(this).children().fadeTo(200, 1);
},
function () {
$(this).children().fadeTo(750, 0);
});
}
});
};
然后我按如下方式使用它,虽然我已经确定了另外两个我需要调用此函数的observable:
this.updateTime = function () {
service.updateBookingTimes(this.id(), this.startDate(), this.endDate());
refreshJQuery();
};
this.startDate.subscribe(this.updateTime, this);
this.endDate.subscribe(this.updateTime, this);
我还实现了@ RPNiemeyer的字段级JQuery订阅解决方案,所以除了他的日期选择器样本之外,我有类似的代码,它将$.button()
重新应用于<a>
标签,另一个转换为复选框进入iPhone风格的开关。