XYZ
XYZ

Reputation: 27387

Dynamic add/remove a component to the page via action

I am creating a FlashCard app and I would like to dynamically insert a component with property into the view via the action inside the route. See screenshot below,

  1. Click "Add Card" button
  2. Dynamically create a card-editor component in the view

enter image description here

I think one possible way to achieve this is to add a conditional handlebar block inside the view and render the component based on the property state; however, I wish to keep my view as clean as possible and think it could be better if I can dynamically render a component to the view only when the action is triggered.

My solution

<div style="margin-left: 200px;">
    {{#if cardEditor}}
        {{app/card-editor}}
    {{/if}}
</div>

In view's controller

export default Ember.Controller.extend({
    cardEditor: false,

    actions: {
        addNewCardEditor() {
            this.set('cardEditor', true));
        }
    }
});

What I have tried

Based on the answer How to programatically add component via controller action in ember 2.x, but it does not work for me. I get an error,

ember.debug.js:41417 Uncaught Error: Cannot instantiate a component without a renderer. Please ensure that you are creating <(subclass of Ember.Component):ember604> with a proper container/registry.

Inside the view HTML,

{{app/side-bar
  addNewCardPressed='addNewCardEditor'
}}

Inside the view route,

import Ember from 'ember';
import CardEditorComponent from '../../components/app/card-editor';

export default Ember.Route.extend({    
    actions: {
        addNewCardEditor() {
            CardEditorComponent.create().appendTo($('body'));
        }
    }
});

Inside the component JS,

actions: {
    addNewCardPressed() {
        this.sendAction('addNewCardPressed');
    }
}

Question

So my question is how can I use the action inside the routes/home/index.js to render the component to the view.

The View HTML,

{{side-bar
  addNewCardPressed='addNewCardEditor'
}}

The Index Page route,

import Ember from 'ember';

export default Ember.Route.extend({
    actions: {
        addNewCardEditor(newCard){}
    }
});

What should I put inside the addNewCardEditor function to generate a component in the view on the fly?

Thanks for your time.

Upvotes: 2

Views: 1250

Answers (1)

Julienm
Julienm

Reputation: 188

in the global.js of your EmberCLI application:


    export function initialize(application) {
        window.EmberApp = application;  // or window.Whatever
    }

Where you want to create dynamically your component, even though it might look like a hack, there might be cleaner way to do it without relying on EmberCLI variables. "App" below is the namespace of your global EmberCLI application that you define in application.js.


    var component = App.CardEditorComponent.extend({ 
        renderer: window.EmberApp.__container__.lookup('renderer:-dom'),
    }).create();

    Ember.setOwner(component , window.EmberApp);
    component.append();

Upvotes: 0

Related Questions