【问题标题】:Angular2 dynamiccomponentloader parameters for @Output@Output 的 Angular2 动态组件加载器参数
【发布时间】:2016-08-26 02:24:38
【问题描述】:

据我了解,您为刚刚使用 DynamicComponentLoader 添加到 DOM 的组件设置 @Input 变量的方式是在调用类似 loadIntoLocation 的内容后使用 promise 块:

this.dcl.loadIntoLocation( Lorem, this.elRef, 'target')
            .then( cmpRef => {

                cmpRef.instance.foo = _self.baz;
            });


export class Lorem {
    public @Input()  foo : String;
    ...

我的问题是在使用动态组件加载器时如何设置@Output?

this.dcl.loadIntoLocation( Lorem, this.elRef, 'target')
            .then( cmpRef => {

                cmpRef.instance.foo = _self.baz;
                cmpRef.instance.changer = _self.change($event);
            });



export class Lorem {
    public @Input()  foo            : String;
           @Output() changer = new EventEmitter();
    ...
    ...
    this.changer.emit("event");

非常感谢您提供的帮助。

【问题讨论】:

  • DynamicComponentLoader添加的组件不支持@Input()和@Output()

标签: input angular output eventemitter


【解决方案1】:

我会利用 subscribe 方法而不是链接到 _self.change($event) 函数的结果,如下所示:

cmpRef.instance.changer.subscribe(($event) => _self.change($event));

由于 beta.16 loadIntoLocation 已被删除,在我的示例中,我将使用 loadNextToLocation,它采用 ViewContainerRef。

应用组件

import {Component, DynamicComponentLoader, ViewChild, ViewContainerRef} from 'angular2/core';

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <div #target></div>
    </div>
  `,
  directives: []
})
export class App {
  baz: string = "Test string";
  @ViewChild('target', {read: ViewContainerRef}) target : ViewContainerRef;
  constructor(private dcl: DynamicComponentLoader) {
    this.name = 'Angular2'
  }
  ngAfterViewInit() {
    this.dcl.loadNextToLocation(Lorem, this.target)
      .then(cmpRef => {
        cmpRef.instance.foo = this.baz;
        cmpRef.instance.changer.subscribe(($event) => this.change($event));
      });
  }
  change($event) {
    alert($event);
  }
}

Lorem 组件

import {Component, Input, Output, EventEmitter} from 'angular2/core';

@Component({
  selector: 'lorem',
  template: `
  <div>{{foo}}</div>
  <button (click)="run()">Run</button>`
})
class Lorem {
  @Input() foo: String;
  @Output() changer = new EventEmitter();
  run() {
    this.changer.emit("event from child");
  }
}

见plunker example

希望对你有帮助。

【讨论】:

  • 非常感谢您的帮助 - 我的代码现在可以工作了。在我关闭这篇文章之前我有两个问题:
  • (1) 如果 baz 是一个对象而不是一个字符串,它会是 lorem 访问的同一个对象(如果以后编辑的话)吗?: cmpRef.instance.foo = this.baz;又名@Input() foo: Object;
  • (2) 每个父实例和每个子 lorem 之间是否是一个封闭的“通道”,没有其他父组件的实例可以“监听”?我担心我的应用程序中的消息过多,我更喜欢您的建议(如果关闭)而不是实现具有验证条件的侦听器。即 this._emitterexample.subscribe( args => { if( args.id === this.localvar ) { ... callback ... } } );
  • 1) 如果 baz 将成为对象并稍后进行编辑(即 this.baz.property = 'test2'),那么每个子对象将是同一个对象。如果您希望在编辑 baz 对象后为每个孩子使用不同的对象,那么您需要使用不可变参数(即 cmpRef.instance.foo = { this.baz.property }) 2)每次从父级调用 loadNextToLocation 都会为 new 启动新的“通道”子组件的实例。我们可以说它是一个封闭的渠道
  • 我想是封装的通道。但听起来没有漂移信号很酷 - 非常感谢您的帮助 yurzui
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2017-01-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多