2015-12-11 4 views
6

Я работаю над большим приложением, и у меня много проблем с данными из моего API и передачей их на мои дочерние компоненты.Доступ к данным api в дочернем компоненте на Vue.js

Ситуация.

Я вызываю свой API из родительского компонента и передавая данные через опору моему дочернему компоненту. Детский компонент отображает данные просто отлично, но я не могу получить доступ к данным в функции ready в моем дочернем компоненте.

Посмотрите: https://jsfiddle.net/kmrfkynf/3/

Как вы можете видеть в консоли, отображение данных в готовой функции дочерних компонентов дает мне пустой объект ...

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

... но дочерние компоненты делают объект очень точным в течение моего повтора.

Таким образом, проблема заключается в том, что дочерний компонент отображается до завершения вызова API от родителя. Когда он завершен, он синхронизирует данные с моим дочерним компонентом, таким образом рендеринг просто прекрасен.

То, что я пытался

Наблюдая пропеллер изнутри моего ребенка компонента. Когда опора «полная», я могу получить к ней доступ. Но это дает мне много проблем при попытке изменить некоторые данные в опоре, потому что это делает каждый раз. Это не то решение, которое я хочу.

Вопрос

Как я могу убедиться, что опора заполнена, когда ребенок компонент готов?

+0

У меня та же проблема, вы нашли хорошее решение этой проблемы? –

+0

Прямо сейчас я использую события для трансляции, когда мои данные готовы –

ответ

1

Проблема в том, что DOM загружен и готов, пока функция AJAX все еще принимает данные. Таким образом, готовый метод компонента накапливается до того, как результаты возвращаются с сервера.

Вы могли вести огонь событие, чтобы сказать ребенку, когда данные от сервера:

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

Это действительно проблема.Я попытался изменить свою скрипку с вашей идеей, но она не работает. https://jsfiddle.net/kmrfkynf/5/ Объект по-прежнему пуст –

+0

Я добавил 'nextTick()', а также инициализировал массив 'items'. Сейчас похоже, что я работаю с моими изменениями выше. –

1

Как @Douglas.Sesar словам, ready метод на item компонентных пожаров до результатов возвращаются с сервера.

Чтобы исправить это, все, что вам нужно добавить это 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); 
    } 
}) 

Этот хук вызывается перед тем компонентом вставки. Компонент не будет вставлен до тех пор, пока не будет вызван обратный вызов done. Обратный вызов done вызывается при изменении items (подробнее см. watch). Следовательно, items будет иметь правильные данные при вызове функции ready.

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

+0

Это действительно приятные решения. Спасибо что подметил это. Может быть, лучше, чем заставить наблюдателя за каждый api i call –