eric eric - 6 months ago 56
AngularJS Question

Binding Angular2 components inside of a Jquery plugin template

I'm working on using a kendo inside of an angular 2 project.

Getting the widget set up correctly is no problem:

ngOnInit() {
let options = inputsToOptionObject(KendoUIScheduler, this);
options.dataBound = this.bound;
this.scheduler = $(this.element.nativeElement)


When that runs, the plugin modifies the DOM (and, to my knowleged, without modifiying the shadow DOM maintained by angular2). My issue is that if I want to use a component anywhere inside of the plugin, like in a template, Angular is unaware of it's existence and won't bind it.


public views:kendo.ui.SchedulerView[] = [{
type: 'month',
title: 'test',
dayTemplate: (x:any) => {
let date =;
let count =[date];
return `<monthly-scheduler-day [date]="test" [count]=${count}"></monthly-scheduler-day>`

The monthly-scheduler-day class:

selector: 'monthly-scheduler-day',
template: `
<div class="badge" (click)=dayClick($event)>Available</div>
export class MonthlySchedulerDayComponent implements OnInit{
@Input() date: number;
@Input() count: number;
constructor() {

console.log('clicked a day');


Is there a "right" way to bind these components inside of the markup created by the widget? I've managed to do it by listening for the bind event from the widget and then looping over the elements it created and using the DynamicComponentLoader, but it feels wrong.


I found some of the details I needed in this thread:

I whipped this service up to handle binding my components:

import { Injectable, ComponentMetadata, ViewContainerRef, ComponentResolver, ComponentRef, Injector } from '@angular/core';

declare var $:JQueryStatic;

export class JQueryBinder {
        private resolver: ComponentResolver,
        private injector: Injector

    public bindAll(
        componentType: any, 
        componentInitializer:(c: ComponentRef<any>, context: {})=>void): 
        let selector = Reflect.getMetadata('annotations', componentType).find((a:any) => {
            return a instanceof ComponentMetadata

        this.resolver.resolveComponent(componentType).then((factory)=> {
            $(selector).each((i,e) => {
                let context = contextParser($(e).html());
                let c = factory.create(this.injector, null, e);
                componentInitializer(c, context);


  • componentType: The component class you want to bind. It uses reflection to pull the selector it needs
  • contextParser: callback that takes the existing child html and constructs a context object (anything you need to initialize the component state)
  • componentInitializer - callback that initializes the created component with the context you parsed

Example usage:

    let parser = (html: string) => {
        return {
            date: parseInt(html)

    let initer =  (c: ComponentRef<GridCellComponent>, context: { date: number })=>{
        let d =;

        c.instance.count =[d]; = d;

    this.binder.bindAll(GridCellComponent, parser, initer );