繁体   English   中英

为NativeScript动态生成Angular2组件

[英]Dynamically generating Angular2 Components for NativeScript

我需要从服务器下载内容并将该内容集成到我的Nativescript / Angular2应用程序中。 内容提供者希望能够格式化文本。 我曾经使用过HtmlView和WebView,但它们有一些限制。

  1. 例如,WebView不能动态增长以适应StackLayout中内容的大小。 并且它创建了一个滚动区域,该区域不适合我们想要提供的用户体验。

  2. HtmlView对HTML / CSS格式的支持非常有限,尤其是在Android上。 <font color='green'>不起作用!

因此,我开始研究动态生成Angular2组件。 那就是从服务器下载模板。 我一直在关注SO Answer中的讨论,并在此方面取得了一些成功。 UI是从运行时提供的简单字符串渲染的,是的! 该示例项目可以在github, dynamic-demo上找到 在此处输入图片说明

为此,我已经更新了NG模板项目,如下所示:

@Component({
    selector: "my-app",
    templateUrl: "app.component.html",
})
export class AppComponent implements AfterViewInit { 
    @ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;

    constructor(
         @Inject('DynamicComponent') private _dynamicComponent: DynamicComponent
    ){};

    ngAfterViewInit() {
        this._dynamicComponent.addComponent(
            this.container,
            ` <Label text="Hello, World!" class="h1 text-center"> </Label>
              <Button text="Tap Again" (tap)="onTap()" class="btn btn-primary btn-active"> </Button>  
            `
        )
    }

    public counter: number = 16;
      public get message(): string {
        if (this.counter > 0) {
            return this.counter + " taps left";
        } else {
            return "Hoorraaay! \nYou are ready to start building!";
        }
    }

    public onTap() {
        this.counter--;
    }
}

增强的核心是我添加的此DynamicComponent类:

import { Injectable, Compiler, Component, NgModule, ViewContainerRef} from '@angular/core'

@Injectable()
export class DynamicComponent {
    constructor(private compiler: Compiler) {}

    public addComponent(container: ViewContainerRef, template: string) {
        @Component({template: template})
        class TemplateComponent {

            onTap(args) {
                console.log('onTap()');
            }
        }

        @NgModule({declarations: [TemplateComponent]})
        class TemplateModule {}

        const mod = this.compiler.compileModuleAndAllComponentsSync(TemplateModule);
        const factory = mod.componentFactories.filter((comp) =>
        comp.componentType === TemplateComponent
        );
        const component = container.createComponent(factory[0]);
    }
}

我想获得有关我的方法的一般反馈。

  1. 这样行吗?
  2. 我是否需要担心原始StackOverflow讨论中的较大答案的问题?
  3. 如何设置它,以便可以将tap操作功能作为DynamicClass的输入提供,而不是像对onTap()那样将它们嵌入到类中?

这是我的问题3的解决方案:

ngAfterViewInit() {
    var component = <any> 
        this._dynamicComponent.addComponent(
            this.container, `
            <Label text="Hello, World!" class="h1 text-center"> </Label>
            <Button text="Tap Again" (tap)="onTap()" class="btn btn-primary btn-active"> </Button>  
         ` );

    component.prototype.onTap = () => {
        this.counter++;
    } 
}

我更新addComponent以返回动态创建的TemplateComponent类,然后像在JS中一样向对象添加一个函数。 有点丑陋,但可以。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM