2012-02-08 5 views
21

Может ли кто-нибудь предоставить примеры кода или документацию по реализации формы с файловым полем с использованием EmberJS и Ember Data?Загрузка файла с данными Ember

Я уже знаком с Ember Data, но я не уверен, как правильно реализовать загрузку файлов.

+0

Если вам нужно поддерживать что-либо ниже IE10, на данный момент все ответы ниже не будут работать. До IE10 вам нужно будет создать форму и скрытый iframe, чтобы она могла нацеливаться и загружать ваш файл отдельно от остальных ваших данных, если вы хотите сделать что-то асинхронное. FileReader и FormData не поддерживаются в IE9. Проще говоря, если вы действительно не ограничиваете свой доступ к «современным» браузерам, эти ответы неадекватны. –

ответ

14

Вот часть адаптера уголек-данных я написал сделать загрузку файлов (тот же сервер -не междоменного)

DS.DjangoRESTAdapter = DS.RESTAdapter.extend({ 
     bulkCommit: false, 

     createRecord: function(store, type, record) { 
      var root = this.rootForType(type), json = {}; 

      var data = new FormData(); 
      data.append('username', record.get('username')); 
      data.append('attachment', record.get('attachment')); 

      this.django_file_ajax('http://localhost:8000/people/new/', "POST", { 
       data: data, 
       context: this, 
       success: function(pre_json) { 
        json[root] = pre_json; 
        this.didCreateRecord(store, type, record, json); 
       } 
      }); 
     }, 

     django_file_ajax: function(url, type, hash) { 
      hash.url = url; 
      hash.type = type; 
      hash.contentType = false; 
      hash.processData = false; 
      hash.context = this; 

      jQuery.ajax(hash); 
     } 

    }); 

})(); 

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

Вот модель уголек-данных для перехода ж/выше адаптер

PersonApp.Person = DS.Model.extend({ 
    id: DS.attr('number'), 
    username: DS.attr('string'), 
    attachment: DS.attr('string') 
}); 

Вот шаблон рули

<script type="text/x-handlebars" data-template-name="person"> 
{{view PersonApp.UploadFileView name="logo_image" contentBinding="content"}} 
</script> 

Вот вид пользовательского уголек

PersonApp.PersonView = Ember.View.extend({ 
    templateName: 'person' 
}); 

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 = e.srcElement.result; 
      var person = PersonApp.Person.createRecord({ username: 'heyo', attachment: fileToUpload }); 
      self.get('controller.target').get('store').commit(); 
     } 
     reader.readAsDataURL(input.files[0]); 
     } 
    } 
}); 

Если вы хотите увидеть всплеск всплеска с этим в действии, проверьте пример загрузки нескольких файлов, которые я сделал недавно у.

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

+0

PersonApp.UploadFielView - это решение, но похоже (для меня) связано с контроллером. Я не эксперт EmberJs, но как улучшить это решение, чтобы разрешить два входных файла на странице (logo_image & detail_image) на примере? – fvisticot

+0

Отличный вопрос - в приведенном выше представлении PersonApp.UploadFileView необходимо немного изменить, чтобы вы не совершали() onload напрямую. Вместо этого у вас может быть кнопка отправки, которая выполняет проверку ввода и, наконец, вызывает commit() после того, как пользователь выберет как логотип, так и детальное изображение (возможно, сможет повторно использовать пользовательский вид выше с дополнительным свойством, таким как динамический идентификатор/имя) –

+0

хороший подход, можете ли вы, пожалуйста, подробно ответить на образец кода? был бы очень полезен для меня (я действительно не эксперт ember.js еще ...) – fvisticot

7

Это довольно простой, общие шаги:

  1. Подключайте вход в пределах Эмбер.
  2. Прочитайте данные из локального файла, указанного во входном элементе.
  3. Закодированные данные в качестве base64.
  4. Задайте значение вашей модели данных ember-данных для строки base64.
  5. На сервере декодируйте строку base64 и voila, данные вашего двоичного файла находятся на сервере.

Следует отметить, что в случае больших файлов с кодировкой base64 возникают проблемы с производительностью, но для небольших изображений или текста это не будет проблемой.


Вы также можете отправить файл «вне» Эмбер данных и нажмите на ответ (например, полезной нагрузки JSON, представляющий модель) в магазине с помощью pushPayload. Если да, то можно использовать FormData или другие методы в XHR2.

Подробнее о стороне клиента манипуляции файлами здесь: http://www.html5rocks.com/en/tutorials/file/dndfiles/

Подробнее о XHR2 и FormData для загрузки файлов здесь: http://www.html5rocks.com/en/tutorials/file/xhr2/

+0

Как отправить файл на сервер? – NkS

+0

Ember.js обычно используют XHR для отправки данных. – sandstrom

+0

Да. Но я должен установить «Content-type» как «multipart/form-data». И мой вопрос: «Я должен прочитать файл и отправить на сервер», как с помощью FileReader api? – NkS

7

Посмотрите на ссылки ниже. Первая ссылка или сообщение в блоге содержит ссылку на рабочий jsfiddle, который обрабатывает загрузку с emberjs. Примечание. Я не писал блог или не создавал скрипку. Но он должен решить вашу проблему.

http://chrismeyers.org/2012/06/12/ember-js-handlebars-view-content-inheritance-image-upload-preview-view-object-binding/ - битая ссылка

http://devblog.hedtek.com/2012/04/brief-foray-into-html5-file-apis.html

+1

Кто-то проголосовал за мой ответ, вы не понимаете, почему? – brg

+3

Я не голосовал, но я хочу сказать, да, много ppl просто голосуют за ничего, абсолютно НИЧЕГО! Я думаю, они просто голосуют, потому что у них слишком много очков ... –

+0

Спасибо @Adam, возможно, они злоупотребляют своей властью. – brg

2

Я попробовал несколько различных решений и в конечном итоге писать адаптер FormData и файла преобразования. Тогда любая модель, которая должна загрузить файл данных может использовать только FormDataAdapter и определить атрибуты файла, как «файл» Тип:

приложение/трансформирует/file.coffee

FileTransform = DS.Transform.extend 
    serialize: (jsonData) -> 
    jsonData 

    deserialize: (externalData) -> 
    externalData 

приложение/модели/user.coffee

User = DS.Model.extend 
    avatar: DS.attr('file') 

приложение/адаптеры/form_data.coffee

get = Ember.get; 

App.FormDataAdapter = ApplicationAdapter.extend 
    ajaxOptions: (url, type, hash) -> 
    hash = hash || {} 
    hash.url = url 
    hash.type = type 
    hash.dataType = 'json' 
    hash.context = @ 

    if hash.data and type != 'GET' and type != 'DELETE' 
     hash.processData = false 
     hash.contentType = false 
     fd = new FormData() 
     root = Object.keys(hash.data)[0] 
     for key in Object.keys(hash.data[root]) 
     if hash.data[root][key] 
      fd.append("#{root}[#{key}]", hash.data[root][key]) 

     hash.data = fd 

    headers = get(@, 'headers') 
    if headers != undefined 
     hash.beforeSend = (xhr) -> 
     for key in Ember.keys(headers) 
      xhr.setRequestHeader(key, headers[key]) 

    hash 

приложение/адаптеры/user.coffee

UserAdapter = FormDataAdapter.extend() 

К сожалению о CoffeeScript, но это вставленный из этого блога: http://blog.mattbeedle.name/posts/file-uploads-in-ember-data/. Здесь вы можете прочитать более подробное описание. Это решение, вероятно, должно быть объединено с входом HTML5 FileReader для включения предварительного просмотра изображений и проверки типа файла на стороне клиента.

Смежные вопросы