W poprzednim wpisie, zobaczyliśmy jak Knockout.js radzi sobie z przepływem danych za pomocą bindowania. W tym wpisie przedstawie, jak upiększyć elementy HTML, za pomocą css’owych atrybutów, zapraszam.
Aby aplikacja działała jeszcze bardziej spójnie, Knockout.js oferuję możliwość formatowania i „stylowania” za pomocą css poszczególnych elementów HTML. Poniżej przedstawie sześć atrybutów odpowiedzialnych za upiększanie naszych elementów HTML:
- text: <value> – Ustawia kontent elementu.
- html: <value> – Ustawia kontent elementu HTML.
- visible: <condition> – Pokazuje albo ukrywa element oparty na pewnych założeniach.
- css: <object> – Dodaje klase css do wybranego elementu.
- style: <object> – Definiuje styl atrybutu danego elementu.
- attr: <object> – Dodaje bezwzględny atrybut do elementu.
Jak wszystkie bindowania Knockout’a, definiowanie wyglądu za pomocą bindowania zawsze odbywa się wewnątrz atrybutu data-bind elementu HTML. Ale w odróżnieniu od płynnego przepływu danych za pomocą bindowania z poprzedniego wpisu, bindowania odpowiedzialne za wygląd działa tylko z poszczególnym powiązanym elementem, nie aktualizuje całego bloku albo zmian związanych z bindowanym kontekstem.
Bindowanie text
Jeżeli chodzi o to bindowanie, to w Knockout.js jest ono banalnie proste. Jak widzieliśmy dotychczas działanie bindowania text odpowiada za wyświetlenie wartości wewnątrz właściwości elementu HTML:
<td data-bind='text: name'></td>
Powinno używać się bindowania text głównie w elementach odpowiedzialnych za tekst (np: <a>, <em>, <span> itp…) Jednakże technicznie można użyć tego do każdego elementu HTML. Tak jakby to był parametr, bindowanie text bierze typ danych i przekształca to na łańcuch znaków przed wyrenderowaniem. Bindowanie text ucieka od istoty HTML’a, więc może być używany bezpiecznie do wyświetlania kontentu użytkownika, poniższy obrazek przedstawi co mam na myśli:
Jest to wartość którą Knockout.js zarządza za kulisami. Dla IE, występuję właściwość innerText, i dla Firefox’a jak też pozostałych przeglądarek używa textContent.
Bindowanie html
Bindowanie html pozwala wyrenderować łańcuch znaków jako znaczniki HTML. Jest to użyteczne jeżeli chcemy dynamicznie generować elementy w ViewModel i wyświetlać je w szablonie. Na przykład, można zdefiniować computed observable nazywając go formattedName w naszym obiekcie Product który przechowuje jakiś HTML:
function Product(name, price, tags, discount){ ... this.formattedName = ko.computed(function() { return "<strong>" + this.name() + "</strong>"; }, this ); }
Teraz, można wyrenderować nazwę za pomocą bindowania html:
<span data-bind='html: featuredProduct().formattedName'></span>
Kiedy mamy zdefiniowany cel aby odseparować warstwę kontentu od warstwy prezentacji, bindowanie html może okazać się wszechstronnym narzędziem, jeżeli używamy go rozsądnie.
Kiedy renderujemy dynamiczny HTML czy bindowanie html albo ASP.NET zawszę bądź pewny, że element został zweryfikowany. Jeśli potrzeba wyświetlić kontent któremu do końca nie ufamy, to powinno użyć się bindowanie text zamiast html.
Bindowanie visible
Podobnie jak bindowanie if i ifnot, bindowanie visible pozwala ukryć i wyświetlić konkretny element oparty na pewnych warunkach. Ale, zamiast usunąć całkowicie element z DOM, bindowanie visible dodaje deklaracje display: none do atrybutu style. Na przykład:
<td data-bind='visible: discount() > 0' style='color: red'>
Poniżej przykład dwóch bindowań dla if i visible:
<td data-bind='if: discount() > 0' style='color: red'></td> <td data-bind='visible:discount() > 0' style='color: red; display: none'> Zaoszczędzisz <span data-bind='text: formattedDiscount'></span>!!! </td>
Kiedy użyć visible albo if? w dużej mierze zależy to od kontekstu. W naszym przypadku lepiej jest użyć bindowania if dzięki temu ilość pustych znaczników <td> jest równa kolumną w każdym wierszu.
To bindowanie bierze taki sam parametr jak if i ifnot. Warunkiem może być właściwość w ViewModel, napisana jako wyrażenie JavaScript albo funkcja zwracająca typ Boolean.
Bindowanie css
Bindowanie css pozwala zdefiniować klasę css dla elementu HTML opartą na pewnych warunkach. Zamiast traktowania tego jako parametr, zostaje pobrany obiekt zawierający nazwy klasy CSS, traktowany jako właściwości, i warunków akceptujących klasę jako wartości.
Na przykład powiedzmy, że chcemy wyświetlić super promocję gdy ilość produktu wyczerpię się do 15%. Jednym ze sposobów aby dodać bindowanie css które wyświetli informację wewnątrz elementu <table> „Zaoszczędziłeś __%” jest:
<td data-bind='if: discount() > 0' style='color: red'> Zaoszczędziłeś <span data-bind='text: formattedDiscount, css: {supersaver: discount() > .15}'></span> !!! </td>
Po pierwsze, warto wiedzieć, że można dodać kilka bindowań do jednego atrybutu data-bind po przecinku. Po drugie, bindowanie css pobiera obiekt {supersaver: discount() > .15} jako argument. Można powiedzieć, że działa to jak mapowanie, gdzie definiujemy klasę CSS która powinna zostać dodana jako element. W tym przypadku klasa .supersaver zostanie dodana kiedykolwiek gdy product discount będzie większy niż 15%, w przeciwnym wypadku zostanie usunięty. Poniżej klasa css którą można dodać gdziekolwiek na stronie.
.supersaver{ font-size: 1.2em; font-weight: bold; }
Jeśli dodamy kolejny produkt jako przecena o 10%, powinniśmy zaobserwować wynik jak poniżej:
Zaoszczędziłeś 20%!!!
Zaoszczędziłeś 10%!!!
Stan zawiera właściwość z obiektu który jest taki sam jak z bindowania if, ifnot i visible. Może być to właściwość, wyrażenie JavaScript albo funkcja.
Bindowanie style
Bindowanie style dostarcza takie same możliwości jak bindowanie css , za wyjątkiem manipulowania atrybutu stylu dla elementu zamiast dodawania lub usuwania klas.
Ponieważ style inline wymagają pary klucz-wartość, składnia tego bindowania/wiązania jest nieco inna:
Zaoszczędziłeś <span data-bind='text: formattedDiscount, style: {fontWeight: discount() > .15 ? "bold" : "normal"}'></span>!!!
Jeśli product discount jest większy niż 15%, Knockout.js wyrenderuje element jak poniżej:
<td style='color: red; font-weight: bold'>
Ale, jeśli jest mniejszy niż 15%, to font-weight zmieni wartość na normal. Wiązanie style może być użyte jako spójnik elementu istniejącego atrybutu style.
Bindowanie attr
Bindowanie attr pozwala dynamicznie definiować atrybuty dla elementu HTML który jest używany jako właściwość ViewModel. Na przykład, jeśli klasa Product ma właściwość permalink, możemy wygenerować link do konkretnej strony z opisem produktu:
<p><a data-bind='attr: {href: featuredProduct().permalink}'>Szczegóły</a></p>
Atrybut href dodaje do tagu <a> hiperłącze, tak to ładnie się nazywa 🙂 Oczywiście jeżeli permalink jest typu observable, można mieć wszystkie benefity Knockout’a jak automatyczne śledzenie zależności. Takie generowanie linków może być bardzo użyteczne. Ale, wiązanie attr może być czymś więcej niż tylko tworzeniem aktywnych linków. Wiązanie pozwala nam na dodanie jakichkolwiek atrybutów do elementów HTML. Dzięki temu mamy otwartą furtkę do integracji Knockout’owego szablonu z innymi bibliotekami DOM.
Podsumowanie
Zobaczyliśmy, że wiązania Knockout’a pozwalają upiększyć wygląd naszych elementów HTML. Głównym celem Knockout.js jest umożliwienie programiście skoncentrowania się na głównych danych z modelu przez automatyczne synchronizowanie widoku kiedykolwiek dane ulegną zmianie. Raz zdefiniowane wiązanie powoduję, że nie musimy się martwić o to później (chyba, że zmienimy strukturę ViewModel).
Ten wpis pokazał, że powyższe wiązania służą tylko do upiększania naszej strony, nie zachodzi tutaj żadna interakcje z komponentami które pozwoliły by użytkownikowi wchodzi w jakąkolwiek interakcję.
Pozdro 🙂