2013-08-09 18 views
6

Chciałbym utworzyć wiązanie "warunkowego kliknięcia" w KnockoutJS. Zasadniczo jest to standardowe wiązanie kliknięć, tak jak w przypadku Knockout, ale warunek musi zostać spełniony, aby można było wykonać dołączoną funkcję. W moim przypadku najlepszą opcją jest utworzenie niestandardowego modułu bindowania, w którym można wywołać standardowe wiązanie kliknięć, jeśli jest to dozwolone.Call standard Knockout click binding z niestandardowego wiązania

ko.bindingHandlers.safeClick = { 
    'init': function(element, valueAccessor, allBindingsAccessor, context) { 
     $(element).click(function() { 
      if(mycondition == true) { 
       // call the standard click binding here -> this is the part I don't know 
      } 
     }); 
    } 
} 

Chcę zastąpić wszystkie moje standardowe powiązania kliknięć z tym niestandardowym powiązaniem. Dlatego ważne jest, aby wywołać powiązanie kliknięcia we właściwy sposób, więc wszystkie parametry podane w HTML są przekazywane do funkcji. Na przykład:

<a href="#" data-bind="click: basevm.gotopage.bind($data, '#homepage')">Home</a> 
<a href="#" data-bind="click: itemvm.activateItem">Activate</a> 

te muszą zostać zastąpione przez

<a href="#" data-bind="safeClick: basevm.gotopage.bind($data, '#homepage')">Home</a> 
<a href="#" data-bind="safeClick: itemvm.activateItem">Activate</a> 

bym bardzo wdzięczny, gdyby mógł mi pomóc w brakującej części w zwyczaj wiązania.

Odpowiedz

11

Prawidłowy sposób przekazać kliknij czekając tutaj jest następujący:

  • Użytkownik przyjmuje oryginalną funkcję (np. Za pomocą valueAccessor())
  • Utwórz nową funkcję valueaccessor, w której zwraca się nową funkcję zawierającą warunek, który następnie wywołuje oryginalną funkcję. I przekaż ten nowy plik wartości do powiązania click.

Więc safeClick będzie wyglądać następująco:

ko.bindingHandlers.safeClick = { 
    'init': function (element, valueAccessor, allBindingsAccessor, 
         viewModel, bindingContext) { 
     var originalFunction = valueAccessor(); 
     var newValueAccesssor = function() { 
      return function() { 
       if (mycondition == true) 
        //pass through the arguments 
        originalFunction.apply(viewModel, arguments); 
      } 
     } 
     ko.bindingHandlers.click.init(element, newValueAccesssor, 
      allBindingsAccessor, viewModel, bindingContext); 
    } 
} 

Demo JSFiddle.

To będzie działać przy pierwszym kliknięciu i nie trzeba ręcznie subskrybować zdarzenia kliknięcia ani wywoływać go za pomocą jQuery.

+0

Ta metoda zakłada, że ​​przekazujesz swój stan jako Knockout obserwowalny w kodzie HTML. Nie chcę tego robić. Zamiast tego chcę ręcznie sprawdzić warunek w kodzie JavaScript za każdym razem, gdy kliknięto element. Czy masz jakieś rady, jak to zrobić? –

+0

Możesz napisać cokolwiek, czego chcesz, zamiast warunku 'if (ko.utils.unwrapObservable (allBindingsAccessor().)). Będzie oceniany za każdym razem, gdy kliknięty zostanie link. Po prostu potrzebowałem warunku obserwowalnego dla mojego demo jsfiddle. Zobacz to zmodyfikowane skrzypce: http://jsfiddle.net/w7nKB/2/ – nemesv

+0

Stworzyłem to skrzypce (http://jsfiddle.net/Ed8Fc/), aby zilustrować problem pomiędzy normalnym wiązaniem kliknięcia a tym niestandardowym wiązaniem. Potrzebuję dostępu do elementu DOM, który wywołał zdarzenie click. Widzisz, że przy normalnym wiązaniu kliknięć jest to ok, ale z wiązaniem safeClick jest zgłaszany błąd w konsoli przeglądarki. –

1

można nazwać następująco:

ko.bindingHandlers.click.init(element, valueAccessor, allBindingsAccessor, context); 

EDIT: Można mannualy wywołać zdarzenie click po raz pierwszy:

ko.bindingHandlers.safeClick = { 
    'init': function(element, valueAccessor, allBindingsAccessor, context) { 
     $(element).click(function() { 
      if(mycondition == true) { 
       ko.bindingHandlers.click.init(element, valueAccessor, allBindingsAccessor, context); 
      } 
     }); 
     if(mycondition == true) { 
      $(element).trigger('click'); 
     } 
    } 
} 
+0

Już natknąłem się na ten podczas wyszukiwania w Internecie. Niestety stwierdziłem, że działa to tylko po drugim kliknięciu elementu kotwicy. Moje rozwiązanie musi działać od pierwszego kliknięcia przez użytkownika. –

+0

Zobacz aktualizację, mam nadzieję, że to pomoże. –