angularjs – 绑定Jquery插件模板内的Angular2组件

我正在使用角度2项目中的kendo.

正确设置窗口小部件没有问题:

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

}

当它运行时,插件修改DOM(并且,对我的知识,不修改由angular2维护的阴影DOM).我的问题是,如果我想在插件内部的任何地方使用组件,就像在模板中一样,Angular不知道它的存在并且不会绑定它.

例:

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

每月调度日课程:

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

    dayClick(event){
        console.log('clicked a day');
    }

}

是否有一种“正确”的方法来绑定窗口小部件创建的标记内的这些组件?我已经设法通过从窗口小部件中侦听绑定事件然后循环它创建的元素并使用DynamicComponentLoader来做到这一点,但感觉不对.

最佳答案 我在这个帖子中找到了我需要的一些细节:
https://github.com/angular/angular/issues/6223

我鞭打这个服务来处理我的组件绑定:

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

declare var $:JQueryStatic;

@Injectable()
export class JQueryBinder {
    constructor(
        private resolver: ComponentResolver,
        private injector: Injector
    ){}

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

        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);
                c.changeDetectorRef.detectChanges();
                c.onDestroy(()=>{
                    c.changeDetectorRef.detach();
                })
            });
        });        
    }
}

PARAMS:

> componentType:要绑定的组件类.它使用反射来拉动所需的选择器
> contextParser:回调,它接受现有的子html并构造一个上下文对象(初始化组件状态所需的任何东西)
> componentInitializer – 使用您解析的上下文初始化创建的组件的回调

用法示例:

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

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

        c.instance.count = this.data[d];
        c.instance.date = d;
    }

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