2016-08-12 8 views
0

В нижней части этого поста в правках Обращается, что я хочу сделать, и то, что почти работалоКак передать массив объектов в качестве опоры для компонента, а затем передать элементы массива в качестве реквизита для вложенных компонентов?

Ниже мое приложение с обоего <oo-upload> и <oo-uploads> компонентов, определенных выше, приложения. По существу <oo-uploads> отображает таблицу из <oo-upload> компонентов для создания файла, загружающего плагин для моего приложения. Переменная uploads - это список всех загрузок, а upload определяет каждую отдельную загрузку.

<body> 

    <script type="x/template" id="oo-upload-template"> 
     <td>@{{ upload.file.name }}</td> 
     <td>@{{ upload.file.size }}</td> 
     <td> 
      <div class="ui indicating progress floated" v-progress="upload.progress"> 
       <div class="bar"><div class="progress"></div></div> 
      </div> 
     </td> 
     <td> 
      <button class="ui primary button" v-on:click="upload" v-if="status < 1">Upload</button> 
      <button class="ui red button" v-on:click="destroy" v-if="status == 2">Delete</button> 
     </td> 
    </script> 

    <script type="x/template" id="oo-uploads-template"> 
     <table class="ui very basic table"> 
      <thead> 
       <tr> 
        <th class="two wide">Filename</th> 
        <th class="two wide">Filesize</th> 
        <th class="ten wide">Status</th> 
        <th class="two wide">Actions</th> 
       </tr> 
      </thead> 

      <tbody> 
       <tr v-show="uploads.length==0"> 
        <td colspan="4" class="ui center aligned">No files added!</td> 
       </tr> 
       <tr v-for="upload in uploads"> 
        <oo-upload :upload="upload"></oo-upload> 
       </tr> 
      </tbody> 

      <tfoot class="full-width"> 
       <tr> 
        <th colspan="4"> 
         <div class="ui right floated small green labeled icon button" v-on:click="uploadDialog"> 
          <i class="plus icon"></i> Upload File 
          <input type="file" style="display:none;" v-el:uploader v-on:change="addFiles" multiple> 
         </div> 
        </th> 
       </tr> 
      </tfoot> 
     </table> 
    </script> 

    <div id="app"> 
     <div class="ui container"> 
      <oo-uploads :uploads="uploads"></oo-uploads> 
     </div> 
    </div> 
    <script type="text/javascript" src="js/app.js"></script> 
</body> 

Вопрос заключается в том, что objUpload объект не передается каждому экземпляру <oo-upload> компонента. Вместо этого отладчик Vue говорит, что компоненту передается функция, а не объект. <oo-uploads> не имеет проблем с получением uploads в качестве опоры.

var Vue = require('vue'), 
    VueRouter = require('vue-router'), 
    VueResource = require('vue-resource'), 
    Vuex = require('vuex'), 
    VueValidator = require('vue-validator'); 

/* 
PLUGINS 
*/ 

Vue.use(VueResource); 

/* 
CUSTOM DIRECTIVES 
*/ 

Vue.directive('progress', { 
    bind: function() { 
     $(this.el).progress(); 
    }, 
    update: function (value) { 
     $(this.el).progress('set percent', value); 
    } 
}); 

/* 
OBJECTS 
*/ 

function objUpload (file) { 
    this.progress = 0; 
    this.file = file; 
    this.status = 0; 
} 

/* 
COMPONENTS 
*/ 

Vue.component('oo-upload', { 
    props: ['upload'], 
    template: '#oo-upload-template', 
    methods: { 
     upload: function() { 
      this.upload.status = 1; 
      this.$http.post('/upload', this.upload.file, { progress: function (pe) { 
       this.progress = Math.floor(pe.loaded/pe.total * 100); 
      }}).then(function (result) { 
       this.upload.status = 2; 
      }, function (result) { 
       this.upload.status = -1; 
      }) 
     }, 
     destroy: function() { 

     } 
    } 
}); 

Vue.component('oo-uploads', { 
    props: ['uploads'], 
    template: '#oo-uploads-template', 
    methods: { 
     uploadDialog: function() { 
      $(this.$els.uploader).click(); 
     }, 
     addFiles: function() { 
      var uploader = this.$els.uploader; 
      for (var i = 0; i < uploader.files.length; i++) { 
       var file = uploader.files[i]; 
       this.uploads.push(new objUpload(file)); 
      } 
     } 
    } 
}) 

/* 
CONSTANTS 
*/ 

Vue.http.headers.common['X-CSRF-TOKEN'] = $('meta[name="_token"]').attr('content'); 

/* 
INSTANCE 
*/ 

var vm = new Vue({ 
    el: '#app', 
    data: { 
     uploads: [], 
    }, 
}); 

EDIT: Если я прохожу uploads массив непосредственно к одному экземпляру <oo-upload> в <oo-uploads>, она проходит полный массив вниз просто отлично, но по какой-то причине он не будет перебирать массив и передать только objUpload объектов.

EDIT2: По сути, я хочу ограничить объем данных, которые я передаю, только для того, что необходимо для этого компонента. Я хочу, чтобы компонент загрузки работал только с назначенной ему загрузкой. Я признаю, что моя практика может быть плохой или что моя реализация может быть невозможна, мне просто нужен указатель на то, как выполнить что-то подобное.

ответ

0

Согласно Vue.js documentation

Поэтому рекомендуется всегда иметь один корневой уровень, простой элемент в шаблонах.

Try обернуть oo-upload-template с tr и изменить

<tr v-for="upload in uploads"> 
    <oo-upload :upload="upload"></oo-upload> 
</tr> 

в

<tr is="oo-upload" v-for="upload in uploads" :upload="upload"></tr> 

Example fixed fiddle

+0

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

+0

Ой, забыл о страшном столе ... как указано в [docs] (http://vuejs.org/guide/components.html#Template-Parsing) _table может содержать только те, tbody, tfoot и tr, и эти элементы должны быть прямыми дочерними элементами таблицы_, потому что будут выгружены _custom-теги и, следовательно, не будут отображаться правильно. Я обновил ответ, чтобы использовать 'is' – pkawiak

+0

Я сделал все изменения, которые вы предложили, но он не начал работать до тех пор, пока я не сломал' upload' и не передал его свойства индивидуально как ''. Я понятия не имею, почему, хотя ... – gopher