我是Knockout.js的新手。
当select()
<input />
变为可见时,最佳方式是什么?
查看:
<p>
Name:
<b data-bind="visible: !editing(), text: name, click: edit"> </b>
<input data-bind="visible: editing, value: name, hasfocus: editing" />
</p>
视图模型:
function PersonViewModel(name) {
// Data
this.name = ko.observable(name);
this.editing = ko.observable(false);
// Behaviors
this.edit = function() { this.editing(true) }
}
ko.applyBindings(new PersonViewModel("Bert Bertington"));
http://knockoutjs.com/documentation/hasfocus-binding.html
谢谢!
答案 0 :(得分:19)
您可以创建一个新的绑定来处理选择。
ko.bindingHandlers.selected = {
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var selected = ko.utils.unwrapObservable(valueAccessor());
if (selected) element.select();
}
};
将此绑定添加到输入字段。
<input data-bind="visible: editing, value: name, hasfocus: editing, selected: editing" />
这是一个小提琴:http://jsfiddle.net/RnCUd/2/
或者,您可以创建一个包装hasfocus
绑定的自定义绑定:
ko.bindingHandlers.hasSelectedFocus = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
ko.bindingHandlers['hasfocus'].init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
ko.bindingHandlers['hasfocus'].update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
var selected = ko.utils.unwrapObservable(valueAccessor());
if (selected) element.select();
}
};
此绑定只是将初始化和更新委托给hasfocus
,如果observable为true,则负责选择元素。使用它而不是hasfocus
。
<input data-bind="visible: editing, value: name, hasSelectedFocus: editing" />
这是一个小提琴:http://jsfiddle.net/RnCUd/1/
答案 1 :(得分:1)
我尝试在上面使用John Earles自定义绑定(感谢John!)以及一个也使用了valueUpdate的文本字段:'afterkeydown'绑定并发现它并没有按预期工作。 (我猜这是因为当其中一个绑定需要触发时,所有绑定都会再次触发,而valueUpdate很可能导致在每个字符写入后触发值绑定)。
经过几次尝试,我为这个问题做了一个半修复,似乎对我有用。基本的想法是,在我们触发hasfocus绑定之前,我们检查所讨论的元素是否已经具有焦点,并且我们实际上只在元素在hasfocus绑定被触发之前没有实际焦点时选择文本。
我使用jquery来检查焦点,但你也可以用其他方式来做。
ko.bindingHandlers.hasSelectedFocus = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
ko.bindingHandlers['hasfocus'].init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var focusBefore = $(element).is(':focus');
ko.bindingHandlers['hasfocus'].update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
var selected = ko.utils.unwrapObservable(valueAccessor());
if (selected && !focusBefore) {
element.select();
}
}
};
编辑:我注意到这种绑定在iOS设备上使用时可能无法正常工作。这样的绑定没有任何问题,但是自动对焦和选择逻辑会导致设备键盘在绑定执行后立即出现,这可能与您想要在这样的设备上发生的情况完全相同。比较一下,在我用来测试的android设备上,一旦执行此绑定,我就不会自动获取键盘。为了我的缘故,我最终创建了另一个绑定,以便通过以下方式在iOS设备上执行任何操作。
ko.bindingHandlers.hasNonIosSelectedFocus = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
if (navigator.userAgent.match(/iPad/i) == null && navigator.platform.indexOf("iPhone") == -1 && navigator.platform.indexOf("iPod") == -1) {
ko.bindingHandlers['hasSelectedFocus'].init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
}
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
if (navigator.userAgent.match(/iPad/i) == null && navigator.platform.indexOf("iPhone") == -1 && navigator.platform.indexOf("iPod") == -1) {
ko.bindingHandlers['hasSelectedFocus'].update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
}
}
};
铊; DR:
如果你使用它并想要迎合平板电脑/智能手机,那么一定要测试这是你实际期望的交互逻辑。