Reputation: 6221
We have a requirement of opening a modal dialog containing a route or a component. We are looking for some modal components, and saw ember-bootstrap's modal is useful.
So,
ModalDialogService.popup(title, bodyComponent, commitHandler, cancelHandler);
or ModalDialogService.popup(title, routeName, commitHandler, cancelHandler);
And how can we do this without violating the Data Down Action Up principle?UPDATED:
What I need is to open any of the current routes in a modal. For example, in a given route hierarchy:
-module1
|-module1.query
|-module1.add
|-module1.update
|-module1.delete
Currently module1.query
has transitions to others. But I want to give an option to the module developers to open any of the add, update, delete routes in a modal. So that query
route doesn't lose its state, when an add operation finished.
Also we have some services used by components. At some conditions, services need to display a modal that has a component.
Upvotes: 0
Views: 1963
Reputation: 1590
You should be able to use a service and component similar to one below to achieve what you want.
Have a look at the twiddle for a demo of how this works exactly, and the code below for quick reference
Your route template could look something like this.
// templates/hasmodal.hbs
{{#bs-modal}}
Modal Content
{{/bs-modal}}
Your route hooks, with service injected
// routes/hasmodal.js
export default Ember.Route.extend({
modalNavigation: Ember.inject.service(),
activate(){
console.log('openingModal')
this.get('modalNavigation').openModal()
},
deactivate(){
console.log('closingModal')
this.get('modalNavigation').openModal()
},
actions: {
onClose(){
console.log('we want to close route')
}
}
})
Your bs-modal or relevant component
//components/bs-modal.js
export default Ember.Component.extend({
modalNavigation: Ember.inject.service(),
isOpen: Ember.computed.alias('modalNavigation.modalOpen'),
classNameBindings: ['isOpen:modalDialog:notOpen'],
actions: {
close(){
this.get('modalNavigation').closeModal()
}
}
})
The bs-modal component template
// templates/components/bs-modal
<div>
{{yield}}
</div>
<button class='close' {{action 'close'}}>Close Me</button>
Your Modal Service to manage state
// services/modal-navigation.js
export default Ember.Service.extend({
modalOpen: false,
openModal(){
this.set('modalOpen',true)
},
closeModal(){
this.set('modalOpen',false)
}
})
UPDATE:
updated twiddle
It basically nests routes that contain a modal underneath a route you want to preserve the state of and show behind the modal.
// router.js [truncated]
Router.map(function() {
this.route('module1',function(){
this.route('query',function(){
this.route('add')
this.route('update', { path: '/update/:item_id' })
this.route('delete', { path: '/delete/:item_id' })
})
})
// templates/modules1/query.hbs
Queried List {{link-to 'add item' 'module1.query.add'}}<br/>
<ul>
{{#each model as |item|}}
<li>
{{item.id}}-{{item.title}}
{{link-to 'u' 'module1.query.update' item}}
{{link-to 'd' 'module1.query.delete' item}}
</li>
{{/each}}
</ul>
{{outlet}}
// templates/module1/query/add.hbs
{{#modal-component isOpen=true onClose=(action "routeClosed")}}
<div>
Title:{{input value=model.title}}
</div>
<button {{action 'save'}}>Save</button>
{{/modal-component}}
Where all the other sub components follow the same modal wrapper principle
Upvotes: 2