Динамическое добавление компонента, используя gridstack и angular2? Jquery $.parseHTML не работает

У меня есть следующий jsfiddle

Я хочу иметь возможность вставлять свой пользовательский компонент в конкретную сетку (например, "")

Прямо сейчас без Angular2 я просто использую:

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

Проблема в том, что я понятия не имею, как я могу сделать что-то вроде:

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);

В angular1 я знаю, что есть компиляция, но в angular2 такого нет.

Мой необычный компонент кнопки прост и выглядит следующим образом:

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

Как я могу динамически добавить компонент необычной кнопки?

2 ответа

Решение

Самый простой способ добавить fancy-button Компонент динамически может быть следующим:

1) Добавить компонент в entryComponents массив вашего модуля

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

2) Получить корневой узел из скомпилированного компонента

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) Используйте его где угодно

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

Вот пример Plunker для вашего случая

Если вы ищете что-то более сложное, то есть много ответов, где вы можете использовать угловой компилятор, чтобы это работало

Вам необходимо использовать класс ViewContainerRef в Angular 2, который предоставляет удобный метод createComponent. ViewContainerRef можно неофициально рассматривать как местоположение в DOM, куда могут быть вставлены новые компоненты.

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

Вот пример рабочего плунжера.

Или вы можете использовать общий HTML-аутлет из этого поста

Другие вопросы по тегам