我编写了一个自定义绑定处理程序,用于切换元素是否为contentEditable。我还希望在编辑元素的内容时更新任何html绑定,因此它会侦听输入事件并更新html绑定(如果可用)。
ko.bindingHandlers.contentEditable = {
update: function (element, valueAccessor, allBindingsAccessor) {
var value = ko.unwrap(valueAccessor());
element.contentEditable = value;
var $element = $(element);
if (value) {
var allBindings = allBindingsAccessor();
var htmlBinding = allBindings.html;
if (ko.isWriteableObservable(htmlBinding)) {
$element.on("input", function (event) {
htmlBinding(element.innerHTML);
});
}
} else {
$element.off("input");
}
}
};
然而,问题在于:
一个jsfiddle说千言万语...... http://jsfiddle.net/93eEr/1/
我对如何处理这件事感到有点难过。
答案 0 :(得分:19)
ko.bindingHandlers.htmlLazy = {
update: function (element, valueAccessor) {
var value = ko.unwrap(valueAccessor());
if (!element.isContentEditable) {
element.innerHTML = value;
}
}
};
ko.bindingHandlers.contentEditable = {
init: function (element, valueAccessor, allBindingsAccessor) {
var value = ko.unwrap(valueAccessor()),
htmlLazy = allBindingsAccessor().htmlLazy;
$(element).on("input", function () {
if (this.isContentEditable && ko.isWriteableObservable(htmlLazy)) {
htmlLazy(this.innerHTML);
}
});
},
update: function (element, valueAccessor) {
var value = ko.unwrap(valueAccessor());
element.contentEditable = value;
if (!element.isContentEditable) {
$(element).trigger("input");
}
}
};
var viewModel = {
editable: ko.observable(false),
content: ko.observable("<i>This</i> is the initial content!")
};
ko.applyBindings(viewModel);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<label>Editable: <input type="checkbox" data-bind="checked: editable"/></label>
<hr>
<div data-bind="contentEditable: editable, htmlLazy: content"></div>
<hr>
<pre data-bind="text: content"></pre>
以最小的改变来做这个伎俩。见http://jsfiddle.net/93eEr/3/
你可以调用绑定处理程序htmlEditable
,也许这比调用它“懒惰”更好。由你决定。
请注意,“input”事件实际上并不需要每次都被绑定。当元素不满足时,它不会发射。
答案 1 :(得分:3)
@ Tomalak的答案是完美的,因此我的支持。
但对于那些到达这里的人,就像我一样:
value:
- esque更新(即:模糊)我建议如下:
ko.bindingHandlers.contentEditable = {
init: function(element, valueAccessor) {
var value = valueAccessor();
function onBlur(){
if (ko.isWriteableObservable(value)) {
value(this.innerHTML);
}
};
element.innerHTML = value(); //set initial value
element.contentEditable = true; //mark contentEditable true
element.addEventListener('blur', onBlur); //add blur listener
}
};
答案 2 :(得分:0)
在以前,我对bdo有问题,可以通过此代码解决它。 此代码也可用于其他contentEditable。 所以我建议:
ko.bindingHandlers.bdoValue =
ko.bindingHandlers.contentEditable = {
'init': function(element, valueAccessor) {
var updateHandler = function() {
var modelValue = valueAccessor(),
elementValue = element.innerHTML;
modelValue(elementValue);
};
ko.utils.registerEventHandler(element, "keyup", updateHandler);
ko.utils.registerEventHandler(element, "input", updateHandler);
},
'update': function(elem, valueAccessor) {
var value = ko.utils.unwrap(valueAccessor())||"";
var current = elem.innerHTML;
if (value !== current) {
elem.innerHTML = value;
}
}
};