【问题标题】:How to show a list of dynamically added components in angular 2如何在角度2中显示动态添加的组件列表
【发布时间】:2018-04-21 16:49:13
【问题描述】:

采用角度特征动态添加组件。

Documentation

Demo

我需要帮助,所以我们直接在页面上显示广告列表,而不是一个接一个地显示。

我认为这就像在 ng-template 元素上添加 *ngFor 一样简单,但它似乎比这更复杂。

我对 angular 2 比较陌生,因此我们将不胜感激。

【问题讨论】:

    标签: angular dynamic components


    【解决方案1】:

    把 loadComponent 函数改成这样:

    loadComponent() {
        let viewContainerRef = this.adHost.viewContainerRef;
    
        for (const ad of this.ads) {
            let componentFactory = this.componentFactoryResolver.resolveComponentFactory(ad.component);
            let componentRef = viewContainerRef.createComponent(componentFactory);
            (<AdComponent>componentRef.instance).data = ad.data;
        }
    }
    

    viewContainer 一个接一个地插入视图。

    编辑:

    关于抛出的错误。最好有一段代码。 这是对问题的更彻底的解释: https://blog.angularindepth.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4

    import { ChangeDetectorRef, (...) } from '@angular/core';
    
    constructor(
        private cd: ChangeDetectorRef,
        private componentFactoryResolver: ComponentFactoryResolver
    ) { }
    
    ngAfterViewInit() {
        this.loadComponent();
        this.getAds();
        this.cd.detectChanges(); 
    }
    

    【讨论】:

    • 它工作得非常好,但有时我会收到此错误:错误:ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。以前的值:'undefined' 知道这是从哪里来的吗?是不是因为我们改变了 ngAfterViewInit 中的模板?
    • 是的,你是对的。我忽略了那个。这是因为 Angulars 变更检测的工作方式。搜索你得到的错误,你会发现大量的详细解释。但基本上问题是当我们改变视图时,当前的变化检测周期已经过去了。这可能会导致 .ts 文件中的数据与呈现的视图之间的不一致。一个简单的解决方案是注入 ChangeDetectorRef 并使用其实例来运行手动更改检测周期。只需在 this.getAds() 之后的 ngAfterViewInit() 中调用其实例的 .detectChanges() 方法
    • 我可能正在推送它,但我似乎无法找到如何将点击等事件绑定到 ng-template 元素。是否可以使用特殊语法来代替 (event)="myFunc()" 形式?
    • 您不能将事件绑定到 ng-template 标签。这只是一种在您希望插入内容的位置显示角度的方法。事实上,当解析 tempate 时,dom 中甚至不存在 ng-template 标签。您当然可以在生成的组件中创建事件绑定,它们将被触发,但是没有直接的方法可以通过正常的父子通信将它们传播到父组件。当然,有一些解决方法。这里给出了一种解决方案:stackoverflow.com/questions/36242119/…
    • 完美!我设法使用componentRef.location.nativeElement.addEventListener( 'click', this.execItemClicked.bind( this, item ) ); 绑定了点击事件我使用了一个 BehaviorSubject 将更改从父级传输到子级,并且所有内容都按应有的方式更新!
    猜你喜欢
    • 2020-04-05
    • 2018-08-11
    • 2017-01-19
    • 2018-09-13
    • 1970-01-01
    • 2018-01-03
    • 2020-11-13
    • 2017-09-09
    • 2017-10-12
    相关资源
    最近更新 更多