Hello World! z Knockout.js

Zabieramy się za pierwsze kody za płoty z Knockout.js, zapraszam 🙂

W tym wpisie zaprezentuję małą aplikację w której zobaczymy jak działa Knockout’owy ViewModel, view, observables, i binding/złączenia podczas tworzenia dynamicznego interface’u użytkownika.

Nim rozpoczniemy kodowanie warto pobrać najnowszą wersję Knockout.js w moim przypadku jest to wersja 3.4.2. Pobieramy plik Knockout.js zapisujemy w naszej aplikacji app. W folderze app znajduję się tylko bibliotek Knockout.js. Teraz utworzymy index.html.

Ja używam do pracy Visual Studio Code, jeżeli robisz tak samo proponuję zainstalować fajną wtyczkę fo vs code „HTML Boilerplate” wystarczy w pustym pliku index.html wpisać html

i kliknąć tab, automatycznie wygeneruje nam szablon html

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> 
<html class="no-js">
<!--<![endif]-->
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<!--[if lt IE 7]>
You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.
<![endif]-->     
</body>
</html>

Nasz szablon na potrzeby tego wpisu wyglądać będzie następująco

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Hello World! z Knockout.js</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>   
<h1>Hello World! z Knockout.js</h1>
Koszyk Przemka
<script type="text/javascript" src="Knockout.js"></script>
</body>
</html>

Zwykły podstawowy plik HTML5 który implementuje bibliotekę Knockout.js. Po otwarciu strony w przeglądarce naszym oczom ukaże się

Hello World! z Knockout.js

Koszyk Przemka

ViewModel

Teraz przejdziemy do zdefiniowania ViewModel’u. Jak wiemy z poprzednich wpisów ViewModel to nic innego jak czysty obiekt JavaScript’owy. Poniżej kod z naszym ViewModelem

var personViewModel = {
    firstName: "Przemek",
    lastName:"Nyweron"
};
ko.applyBindings(personViewModel)
</body>

Stworzyliśmy obiekt „person” który ma właściwości takie jak imię i nazwisko, teraz uruchomi się metoda ko.applyBindings() która mówi Knockout’owi użyj obiektu jako ViewModel dla strony.
Oczywiście jeżeli teraz odświeżysz przeglądarkę nic się nie stanie pozostanie taki sam komunikat jak wcześniej. Aby zobaczyć rezultat musimy teraz załączyć/bind element HTML do obiektu personViewModel.

Binding

W Knockout.js mamy do dyspozycji specjalny atrybut taki jak data-bind który służy do połączenia elementu HTML z ViewModel. Teraz zamienimy wpisaną na sztywno nazwę „Przemka” na

Koszyk <span data-bind='text: firstName'></span>

Atrybut data-bind mówi Knockout’owi co ma wyświetlić w danym elemencie HTML. W naszym przypadku, bindowanie text mówi Knockout’owi wyświetl firstName jako właściwość ViewModel. Teraz po przeładowaniu strony zobaczymy zmianę. Również jeżeli zmienimy atrybut data-bind na text: lastName wówczas zobaczymy nazwę koszyk Nyweron.

Właściwości observable

Mamy ViewModel który wyświetla wynik w elemencie HTML, ale co się stanie jeżeli spróbujemy zmienić właściwość? Po ko.applyBindings()przypiszmy nową wartość do personViewModel.firstName

ko.applyBindings(personViewModel);
personViewModel.firstName = "Tomasz";

Nic się nie stało, Knockout.js nie wyświetli zmian automatycznie na widoku i na stronie cały czas będzie „Koszyk Przemek”. Dzieje się tak ponieważ nie wskazaliśmy Knockout’owi, że właściwość firstName ma zostać zmieniona. Aby Knockout.js mógł śledzić zmiany musi obserwować właściwości które są observable. Zmieńmy troszkę nasz obiekt personViewModel na

var personViewModel = {
    firstName: ko.observable("Przemeka"),
    lastName: ko.observable("Nyweron")
};

Teraz gdy przypisaliśmy wartości firstName i lastName, jako obserwowane czyli ko.observable() Knockout.js wie, że musi śledzić te właściwości i aktualizować gdy wystąpi jakakolwiek zmiana. Aby Knockout.js mógł tę zmianę z aktualizować musimy zmienić jedną rzecz

ko.applyBindings(personViewModel);
personViewModel.firstName("Tomasz");

Teraz gdy uruchomimy nasz przykład, wszystko działa jak należy a właściwość firstName i lastName są teraz observable co pozwala Knockout.js śledzić wszelkie zmiany.

Można uznać, że observables są tak naprawdę funkcjami, nie zmiennymi. Aby uzyskać wartość z observable, należy użyć observable bez argumentów, i aby ustawić wartość należy dać argumenty, łatwiej będzie pokazać o co mi chodzi na poniższym przykładzie

  • Pobierz(get): Używamy obj.firstName() zamiast obj.firstName
  • Ustaw(set): Używamy obj.firstName(„Anna”) zamiast obj.firstName = „Anna”

Dla początkujących ta informacja może być troszeczkę myląca. Dlatego bądź bardzo ostrożny kiedy chcesz przypisać wartość do właściwości observable używając operatora =. To spowoduje, że observable zostanie nadpisany i Knockout zaprzestanie automatycznego aktualizowania widoku.

Niestandardowe obiekty

Nasz generyczny obiekt personViewModel i jego właściwości observable działają super dla naszego prostego przykładu, ale ViewModel może również definiować metody do interakcji z danymi.
Dlatego, ViewModel często jest definiowany jako zwyczajna klasa zamiast generycznego obiektu JavaScript.
Zmieńmy odrobinę nasz obiekt personViewModel.

function PersonViewModel() {
    this.firstName = ko.observable("Przemeka"),
    this.lastName = ko.observable("Nyweron")
};
ko.applyBindings(new PersonViewModel())

W wielu przypadkach tak definiuję się obiekty w Knockout.js teraz możemy dodać metodę

function PersonViewModel() {
    this.firstName = ko.observable("Przemeka"),
    this.lastName = ko.observable("Nyweron")
    this.checkout = function(){
        alert("Alert działa")
    };
};
ko.applyBindings(new PersonViewModel())

Kombinacja danych i metod w jednym obiekcie jest jedną z cech wzorca MVVM. Pozwala to na intuicyjną pracę z danymi. Na przykład, kiedy chcemy sprawdzić proste wywołanie metody checkout() z ViewModel.

Interaktywny binding

Ostatnim przykładem w tym wpisie będzie dodanie przycisku który uruchomi metodę checkout(), aby tego dokonać w elemencie HTML dodajemy binding/wiązanie click, kiedy użytkownik kliknie w przycisk wykona się metoda z naszego ViewModel.

<button data-bind='click: checkout'>Checkout</button>

Gdy klikniemy w nasz przycisk, powinien pojawić nam się alert „Alert działa”.

Podsumowanie

Jak widzimy są trzy kroki aby ustawić Knockout.js

  • Utworzenie obiektu ViewModel i podłączeniu go z Knockout.js
  • Wiązanie/bindowanie elementów HTML z jednym z właściwości ViewModel’u
  • Użycie observable aby pokazać właściwość Knockout’owi

Można pomyśleć, że bindowanie elementów widoku do właściwości observables, są traktowane jako budowanie szablonu HTML dla obiektu JavaScrip. Kiedy szablon jest w pełni zaimplementowany, możemy o nim zupełnie zapomnieć i skupić się na danych w ViewModel. To jest cała idea Knockout.js

W ramach ćwiczeń spróbujcie tak zmodyfikować metodę checkout() aby po kliknięciu zmieniła wyświetlające imię przy koszyku 🙂

Pozdro 🙂

 

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

*