Angular 2在动态添加组件时将数据传递给组件

时间:2016-08-31 07:51:52

标签: angular

我已经通过点击按钮动态添加了一个组件。

以下是我的小部件的代码。将color属性的简单div设置为输入。

Widget.tmpl.html

 div class="{{color}}" (click)="ChangeColor()"

在Widget组件中,我将颜色作为输入。当我手动添加它时,此组件工作正常。但现在我正在尝试动态添加组件,还需要将颜色值传递给Widget组件。

下面是app.component.ts中的代码,我在按钮点击时调用addItem()。

app.component.ts

export class AppComponent  {
  @ViewChild('placeholder', {read: ViewContainerRef}) viewContainerRef;
  private componentFactory: ComponentFactory<any>;

  constructor(componentFactoryResolver: ComponentFactoryResolver, compiler: Compiler) {
    this.componentFactory = componentFactoryResolver.resolveComponentFactory(MyAppComponent);

  }

  addItem () {
   this.viewContainerRef.createComponent(this.componentFactory, 0);
  }

 public  myValue:string = 'red';

 onChange(val: any) { this.myValue = val; } }

在addItem()方法中,我将我的widget组件动态添加到我的视图中。该组件得到了很好的补充。但问题是如何在动态添加时传递color属性。基于我在创建窗口小部件时传递的颜色,我希望它以红色或绿色等显示。如何在此场景中绑定属性?

以下是一些代码:

export class MyAppComponent { 

    @Input() color; 
    @Output('changes') result: EventEmitter<any> = new EventEmitter(); 

    public constructor() { 
    }

    ChangeColor() {
        this.ToggleColor();
        this.result.emit(this.color);// Emitting the color to the parent.        
    }

    ToggleColor() {
        if (this.color == "red")
            this.color = "blue";
        else
            this.color = "red";
    }
}

在上面的代码中,我将我的颜色发送到父app.component.ts,但由于我已动态添加了widget组件,我不知道在哪里添加此代码(changes)=“onChange($ event)”。我尝试在div中添加此代码,如下所示:

<div class="{{color}}" (click)="ChangeColor()" (changes)="onChange($event)"></div>

但它不起作用。

3 个答案:

答案 0 :(得分:12)

var cmpRef = this.viewContainerRef.createComponent(this.componentFactory, 0);
cmpRef.instance.someProp = 'someValue';
cmpRef.instance.someObservable.subscribe(val => this.someProp = val);

答案 1 :(得分:0)

如果您在Google https://netbasal.com/dynamically-creating-components-with-angular-a7346f4a982d中找不到它,我会把它放在这篇文章中,它完美地解释了如何传递数据,对我了解resolveComponentFactory很有帮助,对不起,答案是更多喜欢评论,但我没有足够的声誉。

答案 2 :(得分:0)

我也遇到了同样的问题:组件处理输入数据并根据该数据创建自己的外观。唯一的问题是使用html模板(和预定义的输入数据)将组件作为常规组件添加,并使用componentFactory动态添加组件,并在ngInit角度事件之后设置数据。由于在设置组件的输入数据之前触发了ngInit事件,因此它破坏了所有初始化组件的逻辑。一种可能的解决方案可能是基于允许初始化标记添加灵活的组件初始化,该标记在添加此组件之前和设置输入数据之后设置。

 initComponentData() {
        const canInitData = !this.appService.deniedInitData.value;
        if (canInitData) {
            this.initData();
        } else {

            this.subscriptions.push(
                this.appService.deniedInitData.pipe(filter(x => !x),take(1)).subscribe(() => {
                    this.initData();
                }));
        }
    }

appService-可注射的角度服务

deniedInitData: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

当我们动态添加组件时放置:

this.appService.deniedInitData.next(true);
const cmpRef = this.viewContainerRef.createComponent(this.componentFactory, 0);

const instance = cmpRef.instance;
instance.someProp = 'someValue';                    
this.appService.deniedInitData.next(false);