A proper way to separate concerns?

丶灬走出姿态 提交于 2019-12-25 10:19:07

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!