2012-12-17 34 views
10

Tôi cần tạo thành phần Ember để chọn tệp. Trang của tôi sẽ bao gồm nhiều "thành phần tải lên"Ember.js: Tải lên thành phần tệp

Tôi đã đọc một bài đăng cố gắng triển khai: (https://stackoverflow.com/questions/9200000/file-upload-with-ember-data) NHƯNG UploadFileView được liên kết trực tiếp với bộ điều khiển. Tôi muốn có một cái gì đó chung chung hơn ...

Tôi muốn xóa phụ thuộc App.StoreCardController.set ('logoFile' ..) khỏi chế độ xem hoặc chuyển trường (logoFile) khỏi mẫu .. .

Bất kỳ ý tưởng nào để cải thiện mã này?

App.UploadFileView = Ember.TextField.extend({ 
    type: 'file', 
    attributeBindings: ['name'], 
    change: function(evt) { 
     var self = this; 
     var input = evt.target; 
     if (input.files && input.files[0]) { 
     App.StoreCardController.set('logoFile', input.files[0]); 
     } 
    } 
}); 

và mẫu:

{{view App.UploadFileView name="icon_image"}} 
{{view App.UploadFileView name="logo_image"}} 
+0

Tôi đã trả lời nhận xét của bạn btw và chỉ để làm rõ tệp UploadFileView không phải là bộ điều khiển mà thay vào đó là chế độ xem tùy chỉnh vật. Tôi thành thật nghĩ rằng bạn có thể sửa đổi chế độ xem mà tôi đã hiển thị để làm cho nó trở nên năng động hơn và cho phép giao diện người dùng của bạn có một số đầu vào tải lên tệp –

+0

Đúng vậy, tệp UploadFileView là một đối tượng xem đầy đủ. Vì tôi không phải là chuyên gia ember.js, bạn có thể vui lòng giúp tôi lấy câu trả lời bằng mã mẫu không? – fvisticot

Trả lời

13

tôi hoàn thành một ví dụ hoàn chỉnh để hiển thị này trong hành động

https://github.com/toranb/ember-file-upload

Đây là tay lái cơ bản mẫu

<script type="text/x-handlebars" data-template-name="person"> 
{{view PersonApp.UploadFileView name="logo" contentBinding="content"}} 
{{view PersonApp.UploadFileView name="other" contentBinding="content"}} 
<a {{action submitFileUpload content target="parentView"}}>Save</a> 
</script> 

Dưới đây là các tập tin tùy chỉnh xem đối tượng

PersonApp.UploadFileView = Ember.TextField.extend({ 
    type: 'file', 
    attributeBindings: ['name'], 
    change: function(evt) { 
     var self = this; 
     var input = evt.target; 
     if (input.files && input.files[0]) { 
     var reader = new FileReader(); 
     var that = this; 
     reader.onload = function(e) { 
      var fileToUpload = reader.result; 
      self.get('controller').set(self.get('name'), fileToUpload); 
     } 
     reader.readAsDataURL(input.files[0]); 
     } 
    } 
}); 

Dưới đây là bộ điều khiển

PersonApp.PersonController = Ember.ObjectController.extend({ 
    content: null, 
    logo: null, 
    other: null 
}); 

Và cuối cùng ở đây là quan điểm w/nộp kiện

PersonApp.PersonView = Ember.View.extend({ 
    templateName: 'person', 
    submitFileUpload: function(event) { 
    event.preventDefault(); 
    var person = PersonApp.Person.createRecord({ username: 'heyo', attachment: this.get('controller').get('logo'), other: this.get('controller').get('other') }); 
    this.get('controller.target').get('store').commit(); 
    } 
}); 

này sẽ giảm xuống 2 tập tin trên hệ thống tệp nếu bạn quay lên ứng dụng django

+0

nếu tôi không sử dụng chế độ xem Person và submitFileUpload có bộ điều khiển bên trong, nó có thể gây ra sự cố không? Đối với tôi bên trong controller this.get ('logo') là null @Toran Billups – Nininea

+1

'self.get ('controller'). Set (self.get ('name'), fileToUpload);' cần phải được thay đổi thành 'self .get ('targetObject'). set (self.get ('name'), fileToUpload); ' – Roel

10

CHỈNH SỬA (2015.06): Chỉ cần tạo một giải pháp mới dựa trên một thành phần. Giải pháp này cung cấp nút tải lên có biểu tượng xem trước và xóa. P.S. Các fa lớp là Font Awesome

tay lái Component

<script type="text/x-handlebars" data-template-name='components/avatar-picker'> 
     {{#if content}} 
      <img src={{content}}/> <a {{action 'remove'}}><i class="fa fa-close"></i></a> 
     {{else}} 
      <i class="fa fa-picture-o"></i> 
     {{/if}} 

     {{input-image fdata=content}} 
</script> 

Component Javascript

App.AvatarPickerComponent = Ember.Component.extend({ 
    actions: { 
     remove: function() { 
      this.set("content", null); 
     } 
    } 
}); 

App.InputImageComponent = Ember.TextField.extend({ 
    type: 'file', 

    change: function (evt) { 
     var input = evt.target; 
     if (input.files && input.files[0]) { 
      var that = this; 

      var reader = new FileReader(); 
      reader.onload = function (e) { 
       var data = e.target.result; 
       that.set('fdata', data); 
      }; 
      reader.readAsDataURL(input.files[0]); 
     } 
    } 
}); 

dụ Cách sử dụng

{{avatar-picker content=model.avatar}} 

Câu trả lời cũ

Tôi lấy ví dụ Chris Meyers và tôi làm nhỏ.

Template

{{#view Ember.View contentBinding="foto"}} 
    {{view App.FotoUp}} 
    {{view App.FotoPreview width="200" srcBinding="foto"}} 
{{/view}} 

Javascript

App.FotoPreview= Ember.View.extend({ 
    attributeBindings: ['src'], 
    tagName: 'img', 
}); 


App.FotoUp= Ember.TextField.extend({ 
    type: 'file', 

    change: function(evt) { 
     var input = evt.target; 
     if (input.files && input.files[0]) { 
      var that = this; 

      var reader = new FileReader(); 
      reader.onload = function(e) { 
       var data = e.target.result; 
       that.set('parentView.content', data); 
      } 
      reader.readAsDataURL(input.files[0]); 
     } 
    }, 
}); 
+0

điều này làm việc tuyệt vời cho những gì tôi cần – jakecraige

+0

Bằng cách này tôi chỉ có thể gửi binarydata cho hình ảnh đến máy chủ. Đã phải làm rất nhiều sửa chữa cho phía máy chủ. IS có anyway tôi có thể gửi toàn bộ đối tượng tập tin (tạm thời tập tin) cho máy chủ đường ray (Carrierwave) ?? – Abhaya

+0

Nếu bạn muốn sử dụng multipart-formdata, bạn có thể sử dụng phương thức .serialize() của jQuery trên biểu mẫu. –

0

Marek Fajkus bạn không thể sử dụng .serialize JQuery, nó làm cho không đề cập đến quá trình tải lên tập tin trong tài liệu tại JQuery UI docs

Tuy nhiên, bạn có thể sử dụng JQuery Upload Plugin

Trên thực tế nó đề cập đến nó, nó nói: ". Dữ liệu từ tập tin chọn các yếu tố không được đăng."

0

Trong trường hợp tải nhiều file, bạn có thể muốn sử dụng

{{input type='file' multiple='true' valueBinding='file'}} 
          ^^^^ 

Đây là một giải pháp mà bạn sẽ sử dụng trong upload HTML bình thường.

Ngoài ra, bạn có thể sử dụng 'valueBinding', điều này sẽ cho phép bạn thiết lập người quan sát dựa trên giá trị đó trong thành phần của bạn