{{title}}

'})export class TitleCompon'/> {{title}}

'})export class TitleCompon'/> 将输入值传递给ngComponentOutlet创建的组件? | 所有编程讨论 | zhouni.net

问题 将输入值传递给ngComponentOutlet创建的组件?


我有一个组件,如:

@Component({
  selector: 'app-item',
  template: '<p>{{title}}</p>'
})
export class TitleComponent {
  @Input() title:string;
}

@Component({
  selector: 'app-foo',
  template: '<ng-container *ngComponentOutlet="outlet"></ng-container>'
})
export class FooComponent {
  outlet = TitleComponent;
}

如何在titleComponent的ng-container上传递输入标题值,或者如何设置此值?


5200
2018-02-05 20:18


起源

我即将开始使用ViewContainerRef.createComponent()来替换它。根据我的阅读,您需要获取ngComponentOutlet创建的ComponentRef,然后情况与ViewContainerRef.createComponent相同。您使用componentOutlet.instance并手动设置属于@Input()的属性。它很糟糕,因为各种各样的东西不能自动工作(ngOnChange,OnPush,@ Input(“PublicName”)_privateName)。我希望ngComponentOutlet可以改善这一点,但似乎并非如此。 - Aardvark
可能重复 angular 4+为ngComponentOutlet动态创建的组件分配@Input - Greg Dan
解决方法是添加初始化组件的Service,并使用ngComponentOutletInjector注入自定义Injector。一个你可以从父母那里做的事。 - titusfx
我甚至不敢问@Output ...... - WebDever


答案:


里诺 已经提到过,你可以使用注入器来注入值。

为了完整起见,这是一个动态“标题”值的示例:

export const TITLE = new InjectionToken<string>('app.title'); 


@Component({
  selector: 'app-item',
  template: '<p>{{title}}</p>'
})
export class TitleComponent implements OnInit {
  @Input() title:string;

  constructor(@Inject(TITLE) private titleInjected: string){

  } 

  ngOnInit() {
    this.title = this.title || this.titleInjected;
  }

}


@Component({
  selector: 'app-foo',
  template: '<ng-container *ngComponentOutlet="outlet; injector: myInjector"></ng-container>'
})
export class FooComponent {
  outlet = TitleComponent;
  myInjector: Injector;

  constructor(injector: Injector){
    let title = 'My dynamic title works!';
    this.myInjector = ReflectiveInjector.resolveAndCreate([{ provide: TITLE, useValue: title }], injector);
  }
}


@NgModule({
  providers: [
    { provide: TITLE, useValue: '' }
  ]
})
export class AppModule { }

8
2018-01-29 10:02



请你更新你的答案,它将适用于动态变化 title 来自父组件?我是这样做的 - stackblitz.com/edit/angular-ngcomponentoutlet-input?file=src/... 但也许有更好的解决方案 - Stepan Suvorov


示例解决方案显示在 ngComponentOutlet文档,特别是第二个例子 @Injectable作为 titusfx 还提到了。

以下是您的用例的样子:

@Injectable()
class Info {
  title = 'a little hacky';
}

@Component({
  selector: 'app-item',
  template: '<p>{{info.title}}</p>'
})
export class TitleComponent {
  // @Input() title:string;
  constructor(public info: Info){ }
}

@Component({
  selector: 'app-foo',
  template: '<ng-container *ngComponentOutlet="outlet; injector: myInjector"></ng-container>'
})
export class FooComponent {
  outlet = TitleComponent;
  myInjector: Injector;
  constructor(injector: Injector){
    this.myInjector = ReflectiveInjector.resolveAndCreate([Info], injector);
  }
}

5
2017-11-13 10:02



谢谢你的榜样。甚至可以使用“useValue”提供程序注入动态值:ReflectiveInjector.resolveAndCreate([{provide:DATA,useValue:myData}],injector)。 “TitleComponent”需要注入“DATA”才能获得“myData”。 - Pierre Chavaroche