【问题标题】:Create a Dynamic Component in Angular 2在 Angular 2 中创建动态组件
【发布时间】:2017-07-07 12:22:54
【问题描述】:

嘿,我是 angular 2 的新手,过去一周我一直在玩 angular 2,想知道是否可以生成具有动态模板和动态样式的动态组件。意思就是下面应该是这样的

@Component({
    // 2a
    selector: 'dynamic placeholder',

    // 2b
    styles: [`dynamic styles`] 

    // 2c
    template: `dynmic template`
})

是否可以在角度 2 中做到这一点,我记得这可能在角度 1 中是可能的。

任何帮助将不胜感激(尤其是简单代码的插件)

这是我到目前为止所取得的成就:尝试使用 ComponentFactoryResolver:

@NgModule({
    imports: [BrowserModule],
    declarations: [AppComponent],
    bootstrap: [AppComponent]
})
export class AppModule {
}

@Component({
    selector: 'my-app',
    template: `
        <div>Hello, world!</div>
    `
})
export class AppComponent {
}

@NgModule({
    declarations: [HomeComponent],
    exports: [HomeComponent]
})
export class HomeModule {
}

@Component({
    selector: 'home',
    template: `
        <div>This is home</div>
    `
})
export class HomeComponent {
}

@Component({
    selector: 'hello-world',
    template: `
        <div>
            Hello, world!, {{name}}
            The answer is: {{getAnswer()}}
        </div>
    `
})

export class HelloWorldComponent implements AfterViewInit {
    private name:string = 'You';

    constructor(private helloWorldService: HelloWorldService) {
    }

    ngAfterViewInit(): void {
        this.name = 'Me';
    }

    private getAnswer() {
        return this.helloWorldService.giveMeTheAnswer();
    }
}

@NgModule({
    declarations: [HomeComponent, HelloWorldComponent],
    providers: [HelloWorldService],
    exports: [HomeComponent]
})
export class HomeModule {
}

@Component({
    selector: 'home',
    template: `
        <button (click)="sayHello()">Say hello</button>
        <div>This is home</div>
    `
})

export class HomeComponent {
    constructor(private componentFactoryResolver: ComponentFactoryResolver,
                private viewContainerRef: ViewContainerRef) {
    }

    private sayHello() {
        const factory = this.componentFactoryResolver.resolveComponentFactory(HelloWorldComponent);
        const ref = this.viewContainerRef.createComponent(factory);
        ref.changeDetectorRef.detectChanges();
    }
}

这是一个可以创建动态组件的 plunker,我不知道是否可以创建动态 css,如果有人能回答我的问题,我会很高兴: http://plnkr.co/edit/ZXsIWykqKZi5r75VMtw2?p=preview

【问题讨论】:

  • StackOverflow 不是让您要求人们为您编写代码的地方。向我们展示您的尝试并做出扎实的努力
  • 好的,我会以正确的方式上传它,代码甚至不起作用
  • 与其试图关闭这个帖子,不如互相帮助。我正在努力尝试了解这个主题是否甚至可以在 Angular 2 中使用。如果不是,我不会迁移到 Angular 2 或使用它。我已经在互联网上传递了我的例子,但我的案例没有可靠的答案。

标签: javascript angular


【解决方案1】:

使用 TypeScript 和 Angular2 的最新版本(我相信该功能已在 2.4.0 中发布),您可以创建 1 个基础组件,然后对其进行扩展。将复制属性 (@Input/@Output/@ViewChild) 上的所有装饰器/注释。但是,您必须为每个祖先指定 @Component 属性,即您不能只覆盖 selector,而是覆盖所有内容。这是正确的方法。

另一种方法 -> 使用 reflect-metadata 更新组件类上的装饰器(可能这就是您要寻找的,因为这种情况下您可以一次覆盖 1 个属性),但要小心 export(即public)在您想要覆盖的组件内部使用的所有组件/指令/服务。例如,一些库有多个组件,其中一些应该只在内部使用(即无法以正常方式将其导入模块......但是,您可以尝试providers)。如果您尝试“覆盖”,例如,使用 reflect-metadata 的 css 并且它使用内部组件 - > angular/typescript 会崩溃,因为它无法解析“内部”的东西。你可以从这个答案开始:StackOverflow

【讨论】:

  • 感谢 tim 的快速回答,但在我看来,根据附加的答案,反映元数据是用于继承而不是用于创建动态组件。
  • 我的解释是对的,但我正在寻找可以让我弄清楚如何使用反射元数据等工具的示例
  • 好吧,我可能误解了你的问题。我以为你想在组件之间共享通用功能,而不是即时编码)。
  • 你说得对,我想像代码生成器一样动态编码,但要简单。感谢您的回答和努力。如果我不够清楚,请见谅
猜你喜欢
  • 2017-09-10
  • 2017-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
  • 2018-05-06
  • 2017-03-15
相关资源
最近更新 更多