问题
My app allows the users to manage their documents. When creating one, a user has to either enter the document content manually or select a file from their computer (which would convert many formats to HTML for the user).
Currently, I have a simple FileUploaderView
which is basically an <input type="file">
that listens to file changes, and updates the value
property of the view with an object like { file: { type: SOME_TYPE' }, content: SOME_CONTENT }
.
Then, DocumentsNewController
listens to changes in it and converts supported files to HTML, and puts the result into the document body.
However, doing it this way feels simply wrong and does not allow for simple reuse (which I want to be able to do).
App.DocumentsNewController = Ember.ObjectController.extend
# ... stuff ...
handleDocumentUpload: (->
doc = @get 'documentUpload'
return unless doc
Ember.run =>
@set 'uploadError', false
@set 'unsupportedFile', false
@set 'processingUpload', true
type = doc.file.type
text = ''
try
if type.match /^text\//
text = doc.content
# Convert new lines to br's and paragraphs
text = '<p>' + text.replace(/\n([ \t]*\n)+/g, '</p><p>').replace('\n', '<br />') + '</p>'
else if type == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
text = new DOCX2HTML(doc.content).convert()
else
@set 'unsupportedFile', true
catch error
@set 'uploadError', true
finally
@set 'text', text
Ember.run => @set 'processingUpload', false
).observes 'documentUpload'
And the template is something like
... stuff ...
{{view App.FileUploaderView valueBinding="documentUpload" accept="text/*"}}
What would be the proper way to refactor file converting stuff out of the controller?
I want to be able to do something like:
{{documentHandler resultBinding="documentUpload"}}
and in controller
App.DocumentsNewController = Ember.ObjectController.extend
# ... stuff ...
handleDocumentUpload: (->
if doc = @get 'documentUpload'
@set 'text', doc
).observes 'documentUpload'
My first thought was to make a DocumentHandlerView
which would display the input field, show the spinner, show the errors, parse the document and assign the result to result
(and since controller's template has resultBinding="documentUpload"
, the HTML would trigger the controller's observer).
Using a view for that would allow for easier reuse but I still feel it's not the view's job to parse the document.
Is there a better way?
回答1:
After reading closely your question the best thing that comes in mind would be to create a Ember.Mixin
and then use it for all the controllers that need the same functionality.
Example taken from the ember API docs:
App.Editable = Ember.Mixin.create({
edit: function() {
console.log('starting to edit');
this.set('isEditing', true);
},
isEditing: false
});
// Mix mixins into classes by passing them as the first arguments to
// .extend.
App.CommentView = Ember.View.extend(App.Editable, {
template: Ember.Handlebars.compile('{{#if isEditing}}...{{else}}...{{/if}}')
});
commentView = App.CommentView.create();
commentView.edit(); // outputs 'starting to edit'
The example is only conceptual, but it will be easy to create a mixin
yourself and put all the common logic in there.
Hope it helps.
来源:https://stackoverflow.com/questions/17496726/a-proper-way-to-separate-concerns