简体   繁体   中英

How to open a route in a modal dialog in ember.js?

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,

  1. How can we open any route as a modal dialog ? (If parent route decides a route to be open in a modal, the child route should be open in modal.)
  2. Can we create a service, to pop up a modal dialog? Such as: 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?
  3. Is there any guide, document, tutorial or npm package for implementing modals in ember.js?

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM