Wyświetlanie kolekcji
Binding do kolekcji tworzy się w widoku za pomocą dyrektywy foreach, a po dwukropku podajemy nazwę kolekcji z ViewModelu. Jeżeli w przykładzie poniżej people jest kolekcją obiektów, to name, surname oraz added są kolejnymi properties takich obiektów.
<div data-bind="foreach: people"> <div> <strong data-bind="text: name"></strong> <strong data-bind="text : surname"></strong> <strong data-bind="text : added"></strong> </div> </div>
W ViewModelu kolekcja musi być typu ko.observableArray, co zapewni śledzenie zmian. Warto przygotować sobie również funkcję - konstruktor do szybkiego tworzenia obiektów.
//funkcja konstruktora dla osoby function Person(name, surname){ var self = this; self.name = name; self.surname = surname; self.added = new Date(); } function AppViewModel() { // pozostala czesc inicjalizacji this.people = ko.observableArray([ new Person("John","Doe"), new Person("Jack","The Ripper") ]); } ko.applyBindings(new AppViewModel());
Powyższy kod wyświetli dane sformatowane do naszych potrzeb.
Dodawanie elementów
Jeżeli zajdzie potrzeba dynamicznego dodawania do kolekcji elementów, można stworzyć odpowiednią funkcję wewnątrz ViewModelu.
Od strony widoku można dodać przycisk z bindingiem do zdarzenia click.
<button data-bind="click: addPerson">Add</button>
W ViewModelu należy z kolei dodać funkcję, w której zwiększamy kolekcję używając funkcji push. Wszystkie zmiany w kolekcji spowodują automatyczne zmiany w widoku.
function AppViewModel() { //pozostala czesc inicjalizacji var that = this; this.addPerson = function(){ that.people.push(new Person(that.firstName, that.lastName)); }; }
Edytowanie elementów
Dzięki śledzeniu zależności, każda zmiana wartości automatycznie odświeży kolekcję. Aby edytować elementy za pomocą elementu select, należy nieco zmodyfikować widok:
<div data-bind="foreach: people"> <div> <!--pozostale elementy--> <select data-bind="options: $root.jobs, value: job, optionsText: 'name'"></select> <strong data-bind="text : job().salary"></strong> </div> </div>
Obiekt select dostaje informacje o tym, z której kolekcji ma pobierać listę wartości (tablica jobs z ViewModelu), do którego property elementu z kolekcji people przypisać wartość (obserwowalny element job) oraz które property z elementów jobs wyświetlać jako opcję do wyboru.
Tymczasem po stronie ViewModelu:
function Person(name, surname,job){ var self = this; //pozostale properties self.job = ko.observable(job); } function AppViewModel() { this.jobs = [ {name: "manger", salary : 6000}, {name: "tester", salary : 2000}, {name: "developer", salary : 4000} ]; var that = this; }
Jak widzimy jobs to kolekcja obiektów. Wyświetlamy tylko property name, ale po wybraniu obiektu mamy też dostęp do property salary. Możemy je wyświetlać w widoku za pomocą instrukcji data-bind="text : job().salary", jako odwołanie do property salary z obiektu job, który jest property elementu kolekcji people.
Usuwanie elementów
Po stronie widoku należy dodać element powodujący usunięcie elementu np. poprzez click.
<div data-bind="foreach: people"> <div> <!--pozostale elementy --> <a data-bind="click: $root.removePerson">Remove item</a> </div> </div>
Jako lokalizację funkcji podaje się $root, czyli najbardziej zewnętrzny ViewModel.
function AppViewModel() { var that = this; this.removePerson = function(person){ that.people.remove(person); } }
Agregacja wartości:
Pisanie swoich funkcji wyliczających pewne wartości na całej kolekcji staje się proste dzięki mechanizmowi śledzenie zależności. Gdy chcemy posumować wszystkie wartości i zbindować tę sumę do osobnego elementu, wartość zostanie odświeżona automatycznie przy każdej zmianie na kolekcji. Możemy także zbindować się do właściwości visible i wyświetlać dany element w zależności od spełnienia pewnego warunku logicznego. Na przykład:
<div data-bind="visible: totalSalary()>0"> <p>Total salary:</p> <strong data-bind="text: totalSalary"></strong> </div>
gdzie total salary jest typem ko.computed w ViewModelu.
that.totalSalary = ko.computed(function() { var total = 0; for (var i = 0; i < that.people().length; i++) total += that.people()[i].job().salary; return total; });
Brak komentarzy:
Prześlij komentarz