I have it as a view. IMO the route shouldn’t know anything as to how a view is displayed, but we could still re-use it form multiple places.
Directly from a view
<div> Some markup</div>
{{#modal-view}}
some content
{{/modal-view}}
Have a view that inherits from it so it gets modal
behavior. Then your route simply renders listEditView as usual, but it will show up as a modal.
App.ListsEditView = App.ModalView.extend()
No need for outlet since all the magic is done via CSS, but we could use them.
The ModalView code is simple:
ModalView = Ember.View.extend {
actions:
close: ->
view = @
@$('.modal').one "transitionend", ->
view.controller.send('close')
@$('.modal, .modal-backdrop').removeClass('in')
didInsertElement: ->
view = @
@$('.modal, .modal-backdrop').addClass('in')
@$('.modal-backdrop').on 'click', ->
view.send 'close'
layoutName: 'modal_layout'
}
App.ModalView = ModalView
The layout is simple as well
.modal-backdrop.fade
.modal.fade
div class=loading
= yield
Then your view (list Edit View), simply defines content within some divs used by bootstrap
.modal-header
button.close click="close target=view" type="button" ×
h3 Modify List
.modal-body
= partial 'lists/form'
p.small.faded Created {{time datetime=created_at}}
p.small.faded Last modified {{time datetime=updated_at}}
.modal-footer
input.btn click="close target=view" type="button" value="Close" disabled=loading
input.btn.pull-left click=delete type="button" value="Delete list" disabled=loading
input.btn.btn-primary click=save type="button" value="Save List" disabled=loading
I considered adding a header
and footer
property to the modal-view, that worked fine, so the divs and close button were always defined in the layout, however, I found that I was frequently overriding those sections with more complex content so I moved the responsibility to actual view as shown above.
Then in your controller, you need to implement a close
and a done
action. The first is an opportunity to do something when we’re closing the modal (e.g. cancel the current action). done
simply returns to the previous route. Since this is a common task, we have a mixin with those two. Also in the hook we store the currentPath
before navigating so we know how to go back.
ModalMixin = Ember.Mixin.create {
actions: {
done: ->
@router.transitionTo @get('returnTo')
close: ->
@done() # usually overriden when mixed to cancel/rollback changes
}
beforeModel: ->
@set 'returnTo', @controllerFor('application').get('currentPath')
}
App.ModalRouteMixin = ModalRouteMixin
Hope this helps.