16

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?

2
  • 1
    stackoverflow.com/questions/34784778/… Commented Oct 31, 2016 at 5:35
  • I am not sure I understand what are you trying to do. at the moment gridstack support angular 1 only. Commented Nov 4, 2016 at 21:32

2 Answers 2

6
+500

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

Sign up to request clarification or add additional context in comments.

5 Comments

@yuzui I tried this example, I get this.componentFactoryResolver.resolveComponentFactory is not a function error
@rish can you provide some plunker?
@rish If you want create component with dynamic html then you have to use Compiler. I updated your plunker plnkr.co/edit/GDyJk0GGPOF5opax5cwX?p=preview As you can see i get HtmlElement and add it to document.body
@yuzui thnx it's really helped me, just one question here, can we create these two methods inside normal class which has no [at]Component and [at]Directives?
1

You need to use Angular 2’s ViewContainerRef class, which provides a handy createComponent method. The ViewContainerRef can be informally thought of as a location in the DOM where new components can be inserted.

this.cmpRef = this.vcRef.createComponent(factory, 0, injector, []);

Here's a working plunker example.

Or you can use the generic HTML outlete from this post

1 Comment

There are a lot of DynamicComoponentLoader threads, but those answers are not relevant, because it has been deprecated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.