2015-12-11 12 views
6

Pracuję nad dużą aplikacją i mam problem z danymi z mojego API i przekazaniem ich do moich komponentów podrzędnych.Dostęp do danych api w komponencie potomnym w gotowości przy użyciu Vue.js

Sytuacja.

Wywołuję moje API z komponentu nadrzędnego i przekazuję dane przez prop do mojego komponentu potomnego. Komponent potomny wyświetla dane po prostu dobrze, ale nie jestem w stanie uzyskać dostępu do danych w funkcji gotowości w moim komponencie potomnym.

Spójrz: https://jsfiddle.net/kmrfkynf/3/

Jak widać w konsoli, wyświetlanie danych w ramach komponentów dziecko gotowe funkcji daje mi pusty obiekt ...

ready: function(){ 
    console.log('items from child component', this.items); 
} 

... ale składniki podrzędne renderują obiekt w porządku w ramach mojego powtórzenia.

Problem polega na tym, że komponent potomny jest renderowany przed zakończeniem wywołania interfejsu API od nadrzędnego. Po zakończeniu synchronizuje dane z moim komponentem podrzędnym, dzięki czemu jest w porządku.

Co Próbowałem

Oglądając rekwizyt od wewnątrz mojego składnikiem dziecięcej. Kiedy rekwizyt jest "kompletny", mogę uzyskać do niego dostęp. Ale to daje mi wiele problemów przy próbie modyfikacji niektórych danych w rekwiacie, ponieważ renderuje się za każdym razem. To nie jest rozwiązanie, które chcę.

Pytanie

Jak mogę się upewnić, że prop jest wypełniony, gdy składnik dziecko jest gotowe?

+0

Mam ten sam problem, czy można znaleźć dobre rozwiązanie tego problemu? –

+0

Teraz używam zdarzeń do emisji, gdy moje dane są gotowe. –

Odpowiedz

1

Problem polega na tym, że DOM jest załadowany i gotowy, podczas gdy funkcja AJAX nadal odbiera dane. Tak więc gotowa metoda na komponencie uruchamia się, zanim wyniki wrócą z serwera.

Można ogień zdarzenie powiedzieć dziecku, gdy dane z serwera:

var item = Vue.extend({ 
    props: ['items'], 
    data:function(){return{items:[]}}, 
    template: '<div v-for="item in items">{{ item }}</div>', 
    ready: function(){ 

    this.$on('datahere', function(){ 
     alert(this.items[0].id); 
     //console.log('datahere items', this.items); 

    }) 
    //console.log('items from child component', this.items); 
    } 
}) 

Vue.component('item', item); 

var items = Vue.extend({ 
    ready: function(){ 
    this.init(); 
    }, 
    data: function(){ 
    return { 
     items: {} 
    } 
    }, 
    methods:{ 
    init: function(){ 
     this.getItems(); 

    }, 
    getItems: function(){ 
     this.$http.get('https://api.github.com/users/mralexgray/repos') 
     .success(function(data){ 
      this.$set('items', data); 
      this.$nextTick(function(){ 
       this.$broadcast('datahere', data); 
      }); 

      console.log('items from parent components: ', this.$get('items')); 
     }) 
    } 
    }, 
    template: '<div class="test"><item :items.sync="items"></item></test>', 
    components: {'item': item} 
}) 

Vue.component('items', items); 



var app = new Vue({ 
    el: '#app' 
}) 
+0

To jest rzeczywiście problem.Próbowałem zmodyfikować moje skrzypce za pomocą twojego pomysłu, ale to nie działa. https://jsfiddle.net/kmrfkynf/5/ Obiekt jest wciąż pusty –

+0

Dodałem opcję 'nextTick()', a także zainicjowałem tablicę 'items'. Wygląda na to, że działa teraz z moimi zmianami powyżej. –

1

Jak @Douglas.Sesar powiedział, metoda ready na item składowych pożarów przed wynikami wrócić z serwera.

Aby ustalić, że wszystko, co trzeba dodać to activate hook:

var item = Vue.extend({ 

    activate: function(done) { 
    var unwatch = this.$watch('items', function() { 
     unwatch(); // teardown the watcher 
     done(); // ready to insert the component 
    }); 
    }, 

    props: ['items'], 
    template: '<div v-for="item in items">{{ item }}</div>', 
    ready: function(){ 
    console.log('items from child component', this.items); 
    } 
}) 

że hak jest wywoływana przed wprowadzeniem składnika. Komponent nie zostanie wstawiony, dopóki wywołanie zwrotne done nie zostanie wywołane. Wywołanie zwrotne done jest wywoływane, gdy zmieniono items (szczegóły: patrz watch). W związku z tym items będzie miał prawidłowe dane po wywołaniu funkcji ready.

https://jsfiddle.net/kmrfkynf/8/

+0

To również dobre rozwiązanie. Dziękuję za wskazanie tego. Może być lepiej niż być zmuszonym do obserwowania każdego api, które nazywam –

Powiązane problemy