Ember.js: Загрузить файл
Мне нужно создать компонент Ember для выбора файла.
Моя страница будет содержать несколько компонентов загрузки
Я прочитал сообщение, пытающееся реализовать это: (qaru.site/info/258635/...), но UploadFileView напрямую связан с контроллером.
Я хотел бы иметь нечто более общее...
Я хотел бы удалить зависимость App.StoreCardController.set('logoFile'..) от представления или передать поле (logoFile) из шаблона...
Любая идея улучшить этот код?
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]);
}
}
});
и шаблон:
{{view App.UploadFileView name="icon_image"}}
{{view App.UploadFileView name="logo_image"}}
Ответы
Ответ 1
Я завершил полномасштабный пример, чтобы показать это в действии
https://github.com/toranb/ember-file-upload
Вот основной шаблон руля
<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>
Вот пользовательский объект просмотра файлов
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]);
}
}
});
Вот контроллер
PersonApp.PersonController = Ember.ObjectController.extend({
content: null,
logo: null,
other: null
});
И, наконец, вот представление w/submit event
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();
}
});
Это приведет к удалению 2-х файлов в файловой системе, если вы развернете приложение django
Ответ 2
EDIT (2015.06): просто создано новое решение на основе компонента.
Это решение обеспечивает кнопку загрузки с предварительным просмотром и удалением значка.
Постскриптум Классы fa
Шрифт Awesome
Ручки компонентов
<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>
Компонент 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]);
}
}
});
Пример использования
{{avatar-picker content=model.avatar}}
Старый ответ
Я взял пример Chris Meyers, и я сделал это маленьким.
Шаблон
{{#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]);
}
},
});
Ответ 3
Marek Fajkus вы не можете использовать JQuery.serialize, он не упоминает о загрузке файлов в документации JQuery UI docs
Однако вы можете использовать JQuery Upload Plugin
На самом деле он упоминает об этом, он говорит:
"Данные из элементов выбора файлов не сериализованы".
Ответ 4
В случае загрузки нескольких файлов вы можете использовать
{{input type='file' multiple='true' valueBinding='file'}}
^^^^
Это решение, которое вы использовали бы при обычной загрузке HTML.
Кроме того, вы можете использовать 'valueBinding'
, который позволит вам настроить наблюдателя против этого значения в вашем компоненте.