Выберите() поле ввода с помощью Knockout.js
Я новичок в Knockout.js.
Каков наилучший способ select()
a <input />
, когда он станет видимым?
Вид:
<p>
Name:
<b data-bind="visible: !editing(), text: name, click: edit"> </b>
<input data-bind="visible: editing, value: name, hasfocus: editing" />
</p>
ViewModel:
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
http://jsfiddle.net/RnCUd/
Спасибо!
Ответы
Ответ 1
Вы можете создать новое привязку для выбора дескриптора.
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
и заботится о выборе элемента, если наблюдаемое является истинным. Используйте его вместо hasfocus
.
<input data-bind="visible: editing, value: name, hasSelectedFocus: editing" />
Вот скрипка: http://jsfiddle.net/RnCUd/1/
Ответ 2
Я попытался использовать стандартную привязку 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);
}
}
};
Тл; дг:
Если вы используете это и хотите обслуживать планшеты/смартфоны, убедитесь, что это логика взаимодействия, которую вы действительно ожидаете.