sobota, 26 maja 2012

Knockout - odc. 7

W tym odcinku notatki będące uzupełnieniem do tematu własnych bindingów z odc.3.  Własne bindingi to największa siła Knockout’a ! Tandem Knockout i jQuery jest nie do przecenienia.  Porównując do aplikacji XAML odnoszę wrażenie, że w Knockout pojęcie binding jest traktowane znacznie szerzej i może odgrywać role własnych markup extensions, własnych zachowań czy nawet własnych kontrolek (tak można stworzyć coś z niczego, nawet z pojedynczego taga!), a jednocześnie definiowanie jest bardzo intuicyjne i proste, bardziej proste niż pisanie własnych markup extensions czy nawet … zachowań. Skąd ta prostota? Jak tak obserwuję rozwiązania dla Java Script, to odnoszę wrażenie, że brak silnej typowalności, niekiedy brak konkretnych definicji, mniejsza liczba pojęć, mniej formalizmów temu właśnie sprzyja, tutaj wystarczy o czymś pomyśleć, coś założyć i magicznie wręcz możemy już się do tego odwoływać.

Własne bindingi - uzupełnienia

Binding widzialności z efektami fade (z jQuery)

ko.bindingHandlers.fadeVisible = {

init: function(element, valueAccessor) {

         var display = valueAccessor();

         $(element).toggle(display);

},

update: function(element, valueAccessor, allBindingsAccessor, viewModel) {

         var display = valueAccessor(),

                allBindings = allBindingsAccessor(),

               duration = allBindings.fadeDuration;

         display ?  $(element).fadeIn(duration)  :   $(element).fadeOut(duration);

     }

};

Uwagi

  • allBindingsAccessor - wszystkie inne bindingi z tego samego atrybutu data-bind
  • allBindingsAccessor, viewModel - nie zawsze muszą być w sygnaturach metod

Binding tworzący przycisk z jQuery ustawiający jego opcję disabled w zależności od stanu view modelu

ko.bindingHandlers.jqButton = {

init: function(element, valueAccessor) {      

        $(element).button();

},

update: function(element, valueAccessor, allBindingsAccessor, viewModel) {

var value = valueAccessor(),

$(element).button(“option”, “disabled”, value.enable);

}

};

<button data-bind=”jqButton:  { enable:  stateHasChanged() }, click: save”>Save</button>

Kontrolka rating

ko.bindingHandlers.starRating = {

init: function(element, valueAccessor) {

        $(element).addClass(“starRating”);

        for (var i=0;  i < 5; i++) {

            $(“<span>”).appendTo(element);

        }

        $(“span”, element).each(function(index) {

                $(this).hover(

                         function() {

                              $(this).prevAll().add(this).addClass(“hoverChosen”);

                         },

                        function() {

                              $(this).prevAll().add(this).removeClass(“hoverChosen”);

                 }).click(function()  {

                              var ratingObservable = valueAccessor();

                              ratingObservable(index + 1);

                });

        });

},

update: function(element, valueAccessor) {

   var ratingObservable = valueAccessor();

   $(“span”, element).each(function(index) {

            $(this).toggleClass(“chosen”, index < ratingObservable);

   });

}

}

<span  data-bind=”starRating: rating”></span>

“Nienarzucający się” JS

  • obsługa zdarzeń w szablonach (za pomocą jQuery, czasami też przydatne - ko.dataFor(element), ko.contextFor(element))
  • imperatywne definiowanie bindingów (za pomocą jQuery) np. $(“#total”).attr(“data-bind”, “value:  grandTotal”);

Inne

<select data-bind=”options: [1,2,3,4,5], value: rating” />  //binding z wartością zdefiniowaną inline

Brak komentarzy: