Подтвердить что ты не робот

Значение KnockoutJS, связанное с привязкой данных

У меня есть немного javascript:

function ViewModel() {
    var self = this;
    self.highlight = ko.observable(true);   
}

ko.applyBindings(new ViewModel());

И html, который его дополняет:

<div data-bind="css: { highlighted: highlight }, click: highlight( !highlight() )">
    random string
</div>

То, что я пытаюсь достичь:

  • Класс css "подсвечивается" только для активации, если значение var highlight истинно.
  • Нажатие на div переключит значение bool выделения var
  • Требуемый результат: нажатие на div для активации/деактивации класса css

Что я получаю:

  • Начальное значение выделения true, но класс css начинает деактивироваться (если я изменяю начальное значение на false, активируется класс css: похоже, что я каким-то образом вызвал привязку кликов, когда Я еще ничего не нажал)
  • Класс div css не переключается при нажатии

Я бы предпочел не создавать новую функцию click внутри ViewModel. Я смотрю, если возможно, для небольшого кода, который я могу разместить только внутри линии привязки данных.

Здесь код на JSFiddle: http://jsfiddle.net/4wt4x/1/

Может ли кто-нибудь объяснить, что происходит и что я делаю неправильно?

4b9b3361

Ответ 1

Ваш click: highlight( !highlight() ) неверен. Нажмите, чтобы попытаться выполнить функцию, и когда привязка была инициализирована, подсветка вернет все, что бы ее значение не было, и именно этот клик попытается выполнить (true или false в вашем случае). Вам нужно сделать что-то вроде этого:

В вашем javascript разместите в своей модели:

self.toggleHighlight = function () { self.highlight(!self.highlight()) };

Затем измените привязку, чтобы сказать click: toggleHighlight

Так же: http://jsfiddle.net/KDypD/1/

Вам может потребоваться изменить начальное значение подсветки, чтобы отобразить, как вы хотите, чтобы страница отображалась вначале.

Ответ 2

Я знаю, это старый вопрос, но, возможно, может помочь кому-то. Если вам нужно использовать переключатель во многих местах, возможно, какой-то пользовательский связующий сахар может вам помочь:

Переплет:

ko.bindingHandlers.toggleClick = {
    init: function (element, valueAccessor) {
        var value = valueAccessor();

        ko.utils.registerEventHandler(element, "click", function () {
            value(!value());
        });
    }
};

Применение:

<div data-bind="css: { highlighted: highlight }, toggleClick: highlight">
    random string
</div>

Пример:

http://jsfiddle.net/A28UD/1/

Этот подход сохраняет некоторые мои взгляды очень чистыми. Надеюсь, что это поможет.

Ответ 3

Другим вариантом является использование пользовательского расширения для многократного использования (вместо расширителя используется пользовательская функция, поскольку нет параметров и она выглядит более чистой):

ko.observable.fn.toggleable = function () {
    var self = this;
    self.toggle = function () {
        self(!self());
    };

    return self;
};

Использование

self.highlight = ko.observable(true).toggleable(); 

HTML

<div data-bind="css: { highlighted: highlight }, click: highlight.toggle">
    random string
</div>

Ответ 4

Если вы действительно хотите сделать это inline:

<div data-bind="click: highlight.bind($root, !highlight()), css: { highlighted: highlight } ">
    random string
</div>

где highlight - логическое наблюдаемое.