我有一个子组件类型(childComponent),它允许我通过输入参数注入不同的数据。我在此组件中创建了一个按钮,用于打开父组件(app)中托管的sidenav元素。我使用服务架构来实现(settingsService),这部分工作正常。现在我想将另一个组件注入sidenav(settingComponent),它显示了childComponent的数据。
我使用ngComponentOutlet指令,并且在Sidenav中正确显示了SettingsComponent HTML,但我不知道如何修改实例的输入变量。我读了一些文章,似乎我需要得到ngComponentOutlet创建的ComponentRef来修改变量,但我不知道如何。我认为这种魔法应该在订阅中的某个地方完成。
app.html
<md-sidenav-container class="sidenav-container">
<md-sidenav #sidenav class="settings" align="end" mode="over" >
<ng-container *ngComponentOutlet="settingComponent"></ng-container>
</md-sidenav>
<div>
<a2c-component></a2c-component>
</div>
<div>
// 2nd component (same type with different data)
<a2c-component></a2c-component>
</div>
</md-sidenav-container>
app.ts
@Component({
selector: 'a2c-app',
template: require('./app.html'),
viewProviders: [ NgComponentOutlet ]
})
export class AppComponent implements OnInit {
@ViewChild('sidenav') public settingsBarNavigation: MdSidenav;
private settingComponent: any;
constructor(private settingsBarService: SettingsBarService) { }
public ngOnInit() {
this.settingsBarService.settingsComponent$.subscribe((_value) => {
this.settingComponent = _value.component;
// add settings to new instance here so that
// <instance of component>.parameterObj.someString = _value.settings.title
this.settingsBarNavigation.open();
});
}
}
settingsService.ts
@Injectable()
export class SettingsBarService {
public settingsComponent$: Observable<{ component: any, settings: Object}>;
private settingsComponent: Subject<{ component: any, settings: Object}>;
constructor() {
this.settingsComponent = new Subject<{ component: any, settings: Object}>();
this.settingsComponent$ = this.settingsComponent.asObservable();
}
public openSettings(_settingsComponent: any, _settings { title: string, id: number}) {
this.settingsComponent.next( { component: _settingsComponent, settings: _settings });
}
}
childComponent.html
<div>
<button md-button (click)="openSettings()">Open settings</button>
</div>
childComponent.ts
@Component({
selector: 'a2c-component',
template: require('./childComponent.html')
})
export class ChildComponent {
private settings: Object;
constructor(private setBarService: SettingsBarService) {
// dynamicly filled for each instance of component
this.settings = { title: 'Hello World!', id: 42 };
}
// open DynamicLoadedComponent in sideNav
public openSettings() {
this.setBarService.openSettings(DynamicLoadedComponent, this.settings);
}
}
settingComponent.html
<div>{{ parameterObj.someString }}</div>
settingComponent.ts
@Component({
selector: 'a2c-dynLoaded',
template: require('./settingComponent.html')
})
export class DynamicLoadedComponent {
@Input('parameterObj') public parameterObj: { someString: string };
constructor() { }
}