Пользовательское возвращаемое значение bindingHandler / наблюдаемый
Я не смог найти решение для этого.
Я пытаюсь создать пользовательский bindingHandler для события click по тегу div элемента html.
// custom bindingHandler and observable
<div data-bind="OnClickEvent: HasBeenClicked"></div>
// to show observable's true/false value
<span data-bind="text: 'Observable: ' + HasBeenClicked()"></span>
Этот bindingHandler делает то, что должен, если вы нажмете на div, текст изменится. Однако наблюдаемое говорит, что если ложно.
ko.bindingHandlers.OnClickEvent = {
update: function (element, valueAccessor) {
$(element).text('Click Here: false');
var observable = ko.utils.unwrapObservable(valueAccessor());
$(element).on('click', function () {
observable = !observable;
if (observable) {
$(element).text('Click Here: true');
} else {
$(element).text('Click Here: false');
}
});
}
}
function ViewModel() {
var self = this;
self.HasBeenClicked = ko.observable(false);
}
ko.applyBindings(new ViewModel());
Как настроить наблюдаемый HasBeenClicked для переключения между истиной / ложью при каждом щелчке, как в тексте?
1 ответ
Второй комментарий @nemesv по поводу быстрого исправления, а также тот факт, что ваша привязка выглядит немного странно. Я расширю его до ответа, потому что мне нужна комната.
Сначала быстрое решение:
- Я думаю, что для типа связывания, который вы пишете, более уместно делать свою работу внутри
init
часть; - Вы должны написать обратно в
valueAccessor
изменить значение наблюдаемой (я показываю быстрое и грязное демо ниже);
Вот рабочий пример:
ko.bindingHandlers.OnClickEvent = {
init: function (element, valueAccessor) {
$(element).text('Click Here: false');
var observable = ko.utils.unwrapObservable(valueAccessor());
$(element).on('click', function () {
observable = !observable;
valueAccessor()(observable);
if (observable) {
$(element).text('Click Here: true');
} else {
$(element).text('Click Here: false');
}
});
}
}
function ViewModel() {
var self = this;
self.HasBeenClicked = ko.observable(false);
}
ko.applyBindings(new ViewModel());
div { padding: 10px; background-color: pink; margin-bottom: 10px; cursor: pointer; }
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<div data-bind="OnClickEvent: HasBeenClicked"></div>
<span data-bind="text: 'Observable: ' + HasBeenClicked()"></span>
Тем не менее, я думаю, что такое сочетание jQuery, обработки событий и Knockout довольно сомнительно. Вам следует подумать, не страдаете ли вы XY-проблемой, и не можете ли вы удовлетворить свои требования с помощью существующих обработчиков привязки. Вот один из способов сделать что-то похожее:
function ViewModel() {
var self = this;
self.HasBeenClicked = ko.observable(false);
self.handleClick = function() {
self.HasBeenClicked(!self.HasBeenClicked());
};
}
ko.applyBindings(new ViewModel());
div { padding: 10px; background-color: pink; margin-bottom: 10px; cursor: pointer; }
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<div data-bind="click: handleClick, text: 'Click here: ' + HasBeenClicked()"></div>
<span data-bind="text: 'Observable: ' + HasBeenClicked()"></span>
Говоря о существующих обработчиках привязки, знайте, что есть click
переплет, который может удовлетворить ваши потребности. Если это не так, я бы порекомендовал посмотреть на соответствующий источник (click
перенаправляет на event
связывание, смотрите этот файл в GitHub), чтобы черпать вдохновение для своего собственного обработчика.