Knockout内联编辑绑定

我去寻找一个淘汰内联编辑绑定,但我发现的唯一一个除了jQuery之外还有外部依赖 ,或者使用的不仅仅是绑定 。

所以我想我会分享我想出的简单的一个(其他答案当然是受欢迎的,特别是那些只使用淘汰赛的那些)。

作为替代方案:我用于内联编辑的代码如下所示:

ko.bindingHandlers.hidden = { update: function(element, valueAccessor) { ko.bindingHandlers.visible.update(element, function() { return !ko.utils.unwrapObservable(valueAccessor()); }); } }; ko.bindingHandlers.clickToEdit = { init: function(element, valueAccessor) { var observable = valueAccessor(), link = document.createElement("a"), input = document.createElement("input"); element.appendChild(link); element.appendChild(input); observable.editing = ko.observable(false); ko.applyBindingsToNode(link, { text: observable, hidden: observable.editing, click: observable.editing.bind(null, true) }); ko.applyBindingsToNode(input, { value: observable, visible: observable.editing, hasfocus: observable.editing }); } }; 

http://jsfiddle.net/rniemeyer/Rg8DM/

这是我的内联编辑绑定(小提琴) ,它依赖于jQuery进行一些DOM操作。

HTML:

 

Set an alarm for using Snooze(s).

JS:

 ko.bindingHandlers.inline= { init: function(element, valueAccessor) { var span = $(element); var input = $('',{'type': 'text', 'style' : 'display:none'}); span.after(input); ko.applyBindingsToNode(input.get(0), { value: valueAccessor()}); ko.applyBindingsToNode(span.get(0), { text: valueAccessor()}); span.click(function(){ input.width(span.width()); span.hide(); input.show(); input.focus(); }); input.blur(function() { span.show(); input.hide(); }); input.keypress(function(e){ if(e.keyCode == 13){ span.show(); input.hide(); }; }); } }; 

宽度在点击function中设置,因为Dom Ready上的宽度不可靠:它在0的一半时间内出现。

我也做了一个切换(布尔)你只需要点击切换:

 ko.bindingHandlers.inlineToggle = { init: function(element, valueAccessor, allBindingsAccessor) { var displayType = allBindingsAccessor().type || "bool"; var displayArray = []; if (displayType == "bool") { displayArray = ["True", "False"]; } else if (displayType == "on") { displayArray = ["On", "Off"]; } else { displayArray = displayType.split("/"); } var target = valueAccessor(); var observable = valueAccessor() var interceptor = ko.computed(function() { return observable() ? displayArray[0] : displayArray[1]; }); ko.applyBindingsToNode(element, { text: interceptor }); ko.applyBindingsToNode(element, { click: function(){ target (!target())} }); } }; 

像这样申请(第二个参数是可选的):

  

小提琴还包含一个用于selectmulti-select ,但现在多选选择会使显示跳跃。 我需要解决这个问题。

虽然答案已被接受,但我相信我找到了一个更好的解决方案,所以我想分享一下。

我最终使用了文档中的内容http://knockoutjs.com/documentation/custom-bindings-controlling-descendant-bindings.html#example-supplying-additional-values-to-descendant-bindings

并提出了这个约束的草稿:

 ko.bindingHandlers['textinlineeditor'] = { init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { var observable = valueAccessor(); var value = ko.utils.unwrapObservable(observable); var saveHandler = allBindingsAccessor().editorsavehandler || function (newValue) { observable(newValue); return true; }; var inputType = allBindingsAccessor().editorinputtype || "text"; var vm = new inlineEditorViewModel({ val: value, saveHandler: saveHandler }); $(element).append(""); $(element).append(""); $(element).append("
"); $(element).find("div.pull-right").append(""); $(element).find("div.pull-right").append(""); $(element).find("div.pull-right").append(""); var innerBindingContext = bindingContext.extend(vm); ko.applyBindingsToDescendants(innerBindingContext, element); return { controlsDescendantBindings: true }; } };

我在代码中使用的模型是

 var inlineEditorViewModel = function (init) { var self = this; self.editableValue = ko.observable(init.val); self.lastEditableValue = ko.observable(init.val); self.editing = ko.observable(false); self.edit = function () { self.editing(true); }; self.save = function () { if (init.saveHandler(self.editableValue())) { self.lastEditableValue(self.editableValue()); self.editing(false); } }; self.cancelSave = function () { self.editableValue(self.lastEditableValue()); self.editing(false); }; }; 

在你的HTML中,你会喜欢它

 

注意:我正在使用Bootstrap,因此绑定html中的图标来自。