niedziela, 23 września 2012

[HTML|JS|CSS] KnockoutJS : Custom Binding

KnockoutJS umożliwia tworzenie data bindingu według własnych reguł. Ponadto programista ma możliwość tworzenia reużywalnych ViewModeli, gdzie dane mogą być przekazywane np. poprzez argumenty. Poniższy przykład wykorzystuje te zagadnienia.

<h3 data-bind="text: question"></h3> 
<table>
    <thead><tr><th>Option</th></thead>
    <tbody data-bind="foreach: answers">
        <tr>
            <td data-bind="text: answerText"></td>             
        </tr>    
    </tbody>
</table>
<h3>Your answer:</h3>
<select data-bind="options: letters, value: answer"></select>
<button data-bind="slideBinding: isAnswered() > 0">Finished</button>

Dla przycisku zdefiniowany został specjalny rodzaj bindingu nazwany slideBinding.Aby utworzyć taki binding należy w pliku ze skryptem dodać odpowiedni obiekt slideBinding w ko.bindingHandlers

ko.bindingHandlers.slideBinding = {
  init: function(element, valueAccessor) {
        var shouldDisplay = valueAccessor();
        $(element).css('display','none');
    },
    update: function(element, valueAccessor) {
        var shouldDisplay = valueAccessor();
        shouldDisplay ? $(element).slideDown() : $(element).slideUp();
    }
};

Należy zdefiniować funkcje dla inicjalizacji i zmiany którejś z zależności. Pod valueAccessor dostępne jest wyrażenie logiczne podawane w widoku ( w tym przypadku isAnswered() > 0). Wewnątrz obu funkcji można wykonywać operacje na elemencie, w tym przypadku przy użyciu biblioteki jQuery.

Pozostała część ViewModelu odpowiada za przetworzenie wartości podawanych jako argumenty w odpowiednie properties. Kontrolkę można tworzyć w wielu kontekstach podając za każdym razem inne pytanie i zestaw odpowiedzi.

function answerText(text){
    this.answerText = text;
}

function QuizViewModel(question,answers){
    var self = this;
    self.question = ko.observable(question);
    self.answers = $.map(answers,function(text){return new answerText(text)})
    self.answer = ko.observable("");    
    self.letters = ko.observableArray(["","a","b","c","d"]);                 

    this.isAnswered = ko.computed(function() {
        if(self.answer()===""){ return 0; }
        else{ return 1; }       
    },this);
}

ko.applyBindings(new QuizViewModel("Capital city of Ecuador",
    ["Quito","La Paz","Caracas","Lima"]));

Brak komentarzy:

Prześlij komentarz