我正在尝试实现在组件SettingsComponent
中用户按下按钮并且根AppComponent
中的横幅将更改的功能。
customBanner():void{
this.changeBanner = true;
}
当用户按下SettingsComponent
中的按钮时,将调用上述函数。应用的横幅位于根AppComponent
中:
<div *ngIf ="!changeBanner">
<h2 class="main-header"><img src = "../../../assets/images/banner.jpg" style="max-height:40px"></h2>
</div>
<div *ngIf ="changeBanner">
<h2>Custom Banner</h2>
</div>
<router-outlet></router-outlet>
changeBanner
是AppComponent
的变量。我正在尝试在用户按下按钮时SettingsComponent
AppComponent
中的变量changeBanner
将被更改的位置。
现在我正在尝试这个:
export class AppComponent implements AfterViewInit {
changeBanner = false;
@ViewChild(SettingsComponent)
private settings:SettingsComponent;
ngAfterViewInit(){
this.changeBanner = this.settings.changeBanner;
}
}
甚至在我按settings
页面上的任何内容之前,我就收到错误
无法读取未定义的属性"更改横幅">
谈论this.settings.changeBanner
.
如果我按下按钮,什么也没发生。我不确定我是否以正确的方式去做这件事。
基本上,主题是不同组件之间的通信。通常,当子组件想要与父组件通信时,您将通过@Output
属性使用事件绑定。
但在您的情况下,banner 属性似乎是许多组件之间的共享状态。在这种情况下,最好创建一个保存该状态的服务。所有应该更改横幅的组件都会获得此横幅服务的实例。横幅服务有一个可观察量,当横幅更改时会发出更改。然后,AppComponent 可以订阅该可观察对象并相应地更改横幅。
管理共享状态的另一种选择是 ngrx,它很棒,但学习曲线相当陡峭。
SettingsComponent 的实例必须是 AppComponent 的直接子级,即在 AppComponent 的视图中需要有一个<my-settings></my-settings>
或类似的东西。否则,这不起作用。
除此之外,您应该使用模板绑定或中间服务将数据从一个组件移动到另一个组件。
去掉 AppComponent 中的 @ViewChild(SettingsComponent(。
在AppComponent中创建一个名为bannerChanged(){ this.changeBanner = !this.changeBanner;}
的函数
在 HTML for App 组件中执行以下操作:
<app-settings (bannerChanged)="bannerChanged($event)"></app-settings>
然后在您的设置组件中有这个:
@Output() bannerChanged = new EventEmitter<void>();
...
changeBanner(){
this.bannerChanged.emit();
}
changeBanner 函数将在按下按钮时调用
如果你不想这样,那么制作一个名为"settings"的SettingsReducer并订阅其上的更改,当在SettingsComponent中按下按钮时,调度更改:
//in app.module.ts
StoreModule.forRoot({settings: SettingsReducer})
//in SettingsReducer
export function SettignsReducer(state: SettingStore = SettingsState, { type, payload}){
switch (type) {
case ('SETTINGS_CHANGED'):
return (Object.assign({}, state, { settingValue: payload });
}
}
//in appComponent
constructor(private store: Store<SettingStore>){
this.store.select('settings').subscribe(value => this.changeBanner = value['settingValue'];);
}
//in SettingsComponent
buttonClicked(){
let value = !this.currentValue;
this.store.dispatch({type: 'SETTINGS_CHANGED', payload: value});
}