Search code examples
ember.jsember-cli

Load and unload multiple components in a sidebar using Ember


I have a page where a user is building up an order for a customer. At various stages of the order they may get to a point where they need to add something else. For example, when selecting an address for the customer the customer may have a new address that needs adding, or an existing address may need editing.

I want to be able to load small components on the fly in a right hand sidebar, but there could be any number of them, so I can't just have something like

{{outlet 'right-hand-bar'}}

For example the user may have clicked to add an address, but then may also click a product in the order and I would want to show another component with details on the product, below the add address component. I guess it is kind of like master detail concept, but detail can contain multiple distinct details.

It doesn't feel right to just have a number of outlet's and use the next one available i.e.

{{outlet 'right-hand-bar1'}}
{{outlet 'right-hand-bar2'}}
...

Is there a way to do this in Ember CLI? X number of components in a single outlet?

Edit

I am considering a concept involving creating a sideBar component with a main div

<div class='side-bar-load-area'></div>

and then having a loadComponent action in the sideBar component that takes the name of the component to load.

Not sure how I could load a component by name? I've seen this for a controller:

var comp = App.FooBarComponent.create();
comp.appendTo('#someArea');

and

this.controllerFor('someName');

So ideally would want to combine this and get it working for my sub components?

And also give the sidebar a closeComponent action that a given component could call to unload itself, for an outlet you would do

closeOutlet: function() {
  return this.disconnectOutlet({
    outlet: 'modal',
    parentView: 'application'
  });
}

So again just looking to translate this to work for unloading a component in the DOM, not in a outlet?


Solution

  • Assuming you are running Ember 1.11+, you can use the new component helper

    Basically, you could do something along the lines of:

    templates/main_view.hbs

    <div class="sidebar">
      {{#each componentNames as |componentName|}}
        {{component componentName}}
      {{/each}}
    </div>
    

    and your buttons to create said components in:

    templates/main_view.hbs

    <button {{action "addAddress"}}>New address</button>
    

    and the actions themselves in your controller:

    controllers/main_view.js

    actions: {
      addAddress: function() {
        var controller = this;
        var componentNames = controller.get("componentNames");
        componentNames.pushObject("address");
      }
    }