Pobieranie danych z bazy za pomocą getJSON + knockout + slider


(Zmuszony) #1

Witam,

chcę dynamicznie wypełniać zawartością slider z obrazami.

 

Koncepcja jest prosta - pobieram jQuerrowym getJSON z bazy danych wszystkie informacje (ścieżka do zdjęcia + podpis, który wyświetla się po najechaniu na obrazek), pakuję je do tablicy, którą dzięki frameworkowi knockoutjs mogę ustawić jako observableArray (automatycznie reaguje na zmiany zawartości) a następnie za pomocą knockoutowej pętli foreach wyświetlam wszystko w sliderze (raz to będzie 5 zdjęć, innym razem 10 - nie ma znaczenia właśnie dzięki knockoutowi).

 

Jeżeli na sztywno wpiszę do tablicy dane zdjęć wszystko działa, slider wyświetla się poprawnie:

self.newsList = ko.observableArray([
        { "Title": "Księga Tajemnicza. Prolog", "Author": "Kaliber 44", "Label": "SP Records", "Price": 27.99, "Cover": "Ksiega_Tajemnicza_Prolog_Kaliber_44_Ksiega_Tajemnicza.jpg" },
        { "Title": "The Hunting Party", "Author": "Linkin Park", "Label": "Machine Shop Recordings", "Price": 47.99, "Cover": "linkin_park_the_hunting_party.png" },
        { "Title": "Master of puppets", "Author": "Metallica", "Label": "Elektra Records", "Price": 35.99, "Cover": "metallica_master_of_puppets.png" },
        { "Title": "Złodzieje Czasu", "Author": "Trzeci Wymiar", "Label": "Labirynt Records", "Price": 32.98, "Cover": "3W_złodzieje_czasu.png" }
    ]);

Jeżeli jednak zdecyduję się na pobieranie danych z bazy:

    self.newsList = ko.observableArray();

    $.getJSON("/albums/news", function (allData) {
        var mapped = $.map(allData, function (item) { return new CdCover(item) });
        self.newsList(mapped);
    });
  • klasa CdCover:

    function CdCover(data) {
    this.Author = data.Author;
    this.Title = data.Title;
    this.Price = data.Price;
    this.Cover = data.Cover;
    this.Label = data.Label;
    }

... slider na stronie się rozjeżdża - obrazy nie sią wyświetlane obok siebie a pod sobą (słowem: slider nie działa), pomimo, że w obu przypadkach wyświetlam je w ten sposób więc zgaduję, że to nie wina css. Jako, że obrazy z podpisami się wyświetlają to mam pewność, że dane są pobierane poprawnie więc to nie w tym rzecz.

Poniżej kod za pomocą którego wyświetlam slider i binduję dane:

<!-- Static slider Begin -->   
     <div class="slick-slider" style="width: 980px; height: 325px; margin-top: 20px;" data-bind="foreach: newsList, visible: newsList().length > 0">
        <div class="img-list">
                <x>
                    <img data-bind="attr: { src: 'Images/slider/' + Cover }" />
                    <span class="text-content">
                        <span>
                            <div class="fix-table">
                            <ul class="pricing-table">
                                  <li class="title" data-bind="text: Title"></li>
                                  <li class="bullet-item" data-bind="text: Author"></li>
                                  <li class="description" data-bind="text: Label"></li>
                                  <li class="price" data-bind="text: Price"></li>                                  
                                  <li class="fix-cta-button">
                                      <a href="#" class="button">Więcej</a>&nbsp;
                                      <a href="#" class="button alert">Kup</a>
                                  </li>
                            </ul>
                            </div>
                        </span>
                    </span>
                </x>
        </div>
</div>             
<!-- Static slider End -->

Domyślam się, że problemem może być fakt, iż pobranie danych z bazy chwilę zajmuje a przeglądarka natychmiast ładuje slider, który na chwilę obecną jest pusty. Dopiero później dane są gotowe ale na to już za późno gdyż slider został zbudowany więc wszystko się sypie. Gdy ustawiam dane na sztywno nie ma problemu z pobieraniem danych - w końcu od początku są zaszyte w skrypcie.

 

I tu pojawia się moje pytanie: jak to rozwiązać? Czy istnieje sposób by przeglądarka czekała na pobranie danych z bazy i dopiero potem brała się za renderowanie slidera gdy już będzie miała niezbędną paczkę danych?

 

Używam slidera slick ale problem pojawia się z wieloma innymi.

 

A może się mylę i problem leży całkowicie gdzie indziej?

 

Za wszelkie pomysły będę dozgonnie wdzięczny gdzyż męczę się z tym już kilkanaście dni i nic nie przychodzi mi do głowy :frowning:


(Jim1961) #2

Po pierwsze, nie wiem po co tu w ogóle KnockoutJS.

 

Po drugie, jeżeli http://kenwheeler.github.io/slick/ to to czego używasz, to zaraz po " self.newsList(mapped);" wstaw:

$('.slick-slider').slick({
    setting-name: setting-value
});

co "ręcznie" powinno zainicjalizować plugin.

 

Tak z ciekawości, co to za element "", bo chyba do tyłu z HTMLem jestem? :slight_smile:


(Zmuszony) #3

Jim1961 : kocham Cię :smiley:

 

Wszystko działa, dzięki wielkie!

 

Co do knockouta - używam go na stronie więc zaprzęgnąłem go do slidera żeby z pomocą foreacha i bindowania ułatwić sobie sprawę i zyskać na przejrzystości kodu.

Co do tagu - mój własny, może nie jest to zgodne stricte z najbardziej restrykcyjnymi zasadami ale z tego co mi wiadomo dopuszczalne. Wiem, że powinien mieć bardziej domyślną nazwę, ale to testowy kod.