Search code examples
angulargridstack

Dynamic add component using gridstack and angular2? Jquery $.parseHTML does not work


I have the following jsfiddle

I want to be able to stick my custom component into a specific grid (e.g. "")

Right now without Angular2, I just use:

var el = $.parseHTML("<div><div class=\"grid-stack-item-content\" data-id=\""+id+"\"/><div/>");
this.grid.add_widget(el, 0, 0, 6, 5, true);

The issue is, I have no idea how I could do something like:

var el = $.parseAndCompileHTMLWithComponent("<div><div class=\"grid-stack-item-content\" data-id=\""+id+"\"/><fancy-button></fancy-button><div/>");
this.grid.add_widget(el, 0, 0, 6, 5, true);

In angular1, I know there is a compile, but in angular2, there is no such thing.

My fancy-button component is straightforward and is as follows:

@Component({
  selector: 'fancy-button',
  template: `<button>clickme</button>`
})
export class FancyButton {}

How can I dynamically add the fancy-button component?


Solution

  • The easist way to add fancy-button component dynamically might be as follows:

    1) Add component to entryComponents array of your module

    @NgModule({
      imports:      [ BrowserModule ],
      declarations: [ AppComponent, GridStackComponent, FancyButtonComponent ],
      entryComponents: [ FancyButtonComponent ], // <== here
      bootstrap:    [ AppComponent ]
    })
    export class AppModule { }
    

    2) Get root node from compiled component

    constructor(private vcRef: ViewContainerRef, private componentFactoryResolver: ComponentFactoryResolver) { }
    
    getRootNodeFromParsedComponent(component) {
      const componentFactory = this.componentFactoryResolver.resolveComponentFactory(component);
      const ref = this.vcRef.createComponent(componentFactory, this.vcRef.length, this.vcRef.injector);
      const hostView = <EmbeddedViewRef<any>>ref.hostView;
      return hostView.rootNodes[0];
    }
    

    3) Use it anywhere

    const fancyBoxElement = this.getRootNodeFromParsedComponent(FancyBoxComponent);  
    $('#someId').append(fancyBoxElement);
    

    Here's Plunker Example for your case

    If you're looking for something more complicated then there are a lot of answers where you can use angular compiler to do it working