2012-10-18 14 views
40

Biblioteka knockout.js ma "attr" data binding, która umożliwia dynamiczną zmianę wartości atrybutu elementu HTML (np. "Tytuł"). Jednak w niektórych przypadkach atrybut może lub nie może być potrzebny w zależności od odpowiedniego obserwowanego obiektu związanego. Na przykład, jeśli mój model ma "obserwowany" tytuł, mogę chcieć ustawić atrybut "title", jeśli jest obecny (nie-pusty) lub całkowicie pominąć atrybut, jeśli nie jest obecny (null).Warunkowo dodaj atrybut elementu w knockout.js

Czy nokaut zapewnia jakiś sposób warunkowego ustawienia atrybutu? (Najlepiej bez warunkowo renderowania cały element otwierający znacznik ...)

[Uwaga] To podobnie nazwane pytanie zostało faktycznie rozwiązany przez nokaut w specjalnej obsługi klas CSS i nie odnosi się do tej kwestii (lub własny tytuł) : How to conditionally render an css class with knockoutjs

+1

myślę, że to zachowanie domyślne, jeśli obserwowalne zwraca null, ale mogę się mylić. Czy mogę zadać ci pytanie, dlaczego musisz jawnie nie ustawiać atrybutu zamiast title = "" w przypadku pustej wartości? –

Odpowiedz

67

Potrzebowałem tego przy wyborze (generowałem ręcznie zamiast wbudowanego nokautu).

<option 
data-bind="text: text, 
    attr:{ 
    value:value, 
    'selected': typeof(selected) !== 'undefined' ? selected : null 
    }"> 
Choice X 
</option> 

to mówi zawsze zaktualizować atrybut „Tekst” i dodać atrybut „value”, ale dodać „wybrany” tylko wtedy, gdy dane już ma wartość „wybrany” zdefiniowane.

+6

, więc po prostu wstaw "null" jako wartość atrybutu i nie będzie renderować atrybutów, ładnie! – root

+2

To powinna być poprawiona odpowiedź. Doskonale odpowiada na pytanie w najprostszy sposób. –

+1

Zgadzam się, że to powinna być zaakceptowana odpowiedź. Podczas tworzenia niestandardowego powiązania będzie absolutnie działać, jest to prostsze i bardziej bezpośrednio odpowiada na pytanie. – kiprainey

29

można tworzyć niestandardowe wiążącej attrIf który będzie sprawdzić wartość określonej obserwowalnym logiczną przed dodawać lub nie atrybuty. Zobacz ten przykład:

ko.bindingHandlers.attrIf = { 
    update: function (element, valueAccessor, allBindingsAccessor) { 
     var h = ko.utils.unwrapObservable(valueAccessor()); 
     var show = ko.utils.unwrapObservable(h._if); 
     if (show) { 
      ko.bindingHandlers.attr.update(element, valueAccessor, allBindingsAccessor); 
     } else { 
      for (var k in h) { 
       if (h.hasOwnProperty(k) && k.indexOf("_") !== 0) { 
        $(element).removeAttr(k); 
       } 
      } 
     } 
    } 
}; 

<a href="#" data-bind="attrIf: {title: title, _if: flag}">link</a> 
+0

Genialny, ale jeden poważny problem - jeśli mam atrybut inny niż "tytuł" i nie chcę, aby _if się do niego odnosiło ... Ciągle będzie. Mimo to idea kodu jest dobra. – Phil

+5

zawsze możesz dodać drugi atrybut, używając standardowego wiązania 'attr' (na które nie ma wpływu flaga _if). przykład: data-bind = "attrIf: {title: title, _if: flag}, attr: {otherAttr: val}" – gbs

+0

Polecam mieć więcej logiki wokół tego usunięcia na dole ... ta odpowiedź nie działa, jeśli chcesz warunkowo zastąpić atrybut, który już istnieje w elemencie. obrazek następujący: MrTristan

2

Chciałbym móc odpowiedzieć na @gbs, ale nie mogę. Moim rozwiązaniem byłoby posiadanie dwóch tego samego elementu HTML, jednego z atrybutem, jednego bez i warunku nokautu, aby dodać jeden z nich zgodnie z elementem. Wiem również o tym niestandardowym dopasowywaniu, ale które z rozwiązań jest bardziej wydajne?

+0

Co zrobić, jeśli masz 5 różnych atrybutów tego samego elementu? Dużo zabawy w perspektywie ... – Samuel

Powiązane problemy