2013-02-14 14 views
18

Mam kawałek javascript:KnockoutJS wartość przełączanie w danych-wiążą

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

ko.applyBindings(new ViewModel()); 

a html, który uzupełnia go:

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

Co usiłuję osiągnąć:

  1. "Podświetlona klasa css" aktywowana tylko po wyróżnieniu var jest
  2. Kliknięcie na div przełącza wartość bool var podświetleniem
  3. wynik Poszukiwany kliknięciu na div, aby aktywować/dezaktywować jego klasa css

Co dostaję:

  1. Wartość początkowa podświetleniem to jest true, ale klasa css jest dezaktywowana (jeśli zmienię wartość początkową na false, aktywowana jest klasa css: wydaje mi się, że w jakiś sposób uruchomiłem kliknięcie, gdy nic jeszcze nie kliknąłem)
  2. klasa css diva nie włącza się kliknij

Wolałbym nie tworzyć nowych odpowiednich funkcji kliknij wewnątrz ViewModel. Czekam, jeśli to możliwe, na fragment kodu, który mogę umieścić wyłącznie w linii danych.

Oto kod na JSFiddle: http://jsfiddle.net/4wt4x/1/

Może ktoś wyjaśnić, co się dzieje i co robię nieprawidłowo?

Odpowiedz

19

Twoja click: highlight(!highlight()) jest niepoprawna. Kliknij, aby spróbować uruchomić funkcję, a po inicjalizacji powiązania, podświetlona wartość powróciłaby niezależnie od jej wartości i jest to, co kliknięcie będzie próbowało wykonać (true lub false w twoim przypadku). Musisz zrobić coś takiego:

w twojej JavaScript, miejsce w modelu:

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

następnie zmienić wiązanie powiedzieć click: toggleHighlight

tak: http://jsfiddle.net/KDypD/1/

może trzeba aby dostosować początkową wartość podświetlenia, aby odzwierciedlić początkową stronę.

+0

Dzięki za odpowiedź. Czy nie ma sposobu, aby zrobić to samodzielnie w samym wiązaniu danych? Właśnie tego szukam, jeśli to możliwe. – dk123

+1

Osobiście uważam za złą praktykę umieszczanie czegoś takiego w wiązaniu. Chodzi o to, aby twój widok był oddzielony od twojego javascriptu. Jednakże, jeśli naprawdę tego chcesz, możesz po prostu kliknąć: function (self) {self.highlight (! Self.highlight())} dla wiązania, ale nie polecam, ponieważ od tego czasu debugowanie zakończyłoby się do znalezienia javascript w dwóch miejscach, zamiast jednego. Staje się problemem przy większych projektach z wieloma współpracownikami. –

+0

Dzięki za odpowiedź i dodatkowy komentarz do struktury widoku. Pójdę z twoim pomysłem i utworzę funkcję w javascript. Dzięki! – dk123

38

Wiem, że to stare pytanie, ale może ktoś może pomóc. Jeśli trzeba użyć przełącznika w wielu miejscach, może jakiś cukier zwyczaj wiązania mogłyby pomóc:

Oprawa:

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

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

Zastosowanie:

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

Przykład :

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

Takie podejście utrzymuje niektóre z moich poglądów bardzo czystsze. Mam nadzieję, że to pomoże.

+2

To powinna być akceptowana odpowiedź IMO. – MattSizzle

+1

ko.utils.registerEventHandler +1 – Moon

+0

To było dokładnie to, czego szukałem – Koscik

4

Jeśli naprawdę chcesz to zrobić inline:

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

gdzie atrakcją jest logiczna obserwowalne.

6

Inną opcją jest użycie do ponownego użycia niestandardowego rozszerzenia funkcji (funkcja zwyczaj jest stosowany zamiast rozcieńczalnika, ponieważ nie istnieją żadne parametry i wygląda czystsze):

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

    return self; 
}; 

Wykorzystanie

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

Html

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

wolę tę metodę, ponieważ można wtedy użyć 'funkcjonalność toggle' w jakimkolwiek wypadku, lub nawet w kodzie. – Grinn