Ember Modals - Toggle and best way to structure


#1

Super new to Ember and trying to wrap my head around how data is passed from parent components to children and back up so any help is appreciated.

My goals is to have two buttons and each of them call their respective modal. The parts I’m stuck on is:

  1. Best way to structure a reusable modal component
    • Should I pass in a template to the {{modal-dialog}}?
    • How can I structure this so it’s as reusable as possible?
  2. How to close a modal (toggle the isShowingModal) from inside the modal
    • I can get the button to pop open the modal, but I can not get it to close from within the modal. What am I doing wrong?

My setup is I have a parent component “Component A” and inside of it I have the modal component. I am using the ember addon Ember Modal Dialog by Yapplabs. I have researched several articles but haven’t found one that seems to point me in the right direction as to what I’m doing wrong. Closest one I found was Simple Modal Dialog

Thanks in advance!

My templates

Parent Component

// templates/component-a.hbs
<button id="btn-1" {action 'toggleModal'}}>
    Modal One
</button>
<button id="btn-2" {{action 'toggleModal'}}>
    Modal Two
</button>
{{#if isShowingModal}}
    {{#modal-dialog
      targetAttachment="center"
      clickOutsideToClose=true}}
          {{modal-element}}
    {{/modal-dialog}}
{{/if}}

Modal Component

// templates/components/modal-element.hbs
<div>
    <div id="modal-one" class="modal-header">
        <h1>Modal One</h1>
        <button type="button" class="button-close" {{action 'toggleModal'}}> 
            <span>X</span>
        </button>
    </div>
    <div id="modal-two" class="modal-header">
        <h1>Modal Two</h1>
        <button type="button" class="button-close" {{action 'toggleModal'}}> 
            <span>X</span>
        </button>
    </div>
</div>

Controller and Component Js Files

Parent Component

// controller/component-a.js
export default Ember.Controller.extend({
    isShowingModal: false,
    actions: {
        toggleModal() {
            this.toggleProperty('isShowingModal');
        }
    }
});

Modal Component

// components/modal-element.js
export default Ember.Component.extend({
  isShowingModal: false,
  actions: {
    toggleModal() {
      this.toggleProperty('isShowingModal');
    }
  }
});

#2

Learn about closure actions for passing data up. See https://guides.emberjs.com/v2.11.0/components/triggering-changes-with-actions/


#3

Closure actions have been a life saver. Thanks!


#4

Your best bet would be to make component-a completely responsible for toggling the modal. So instead you should pass the toggleModal action to the model-element:

{{modal-element closeAction=(action 'toggleModal')}}

Now model-element only needs to trigger the given action:

actions: {
  onCloseButtonClicked() {
    if (this.get('closeAction')) {
      this.get('closeAction')();
    }
  }
}