我对如何做到这一点不知所措:
我想在一个组件中定义一个将由同级组件呈现的部分,但要使用原始组件的上下文: 想象以下组件: A , B , C 和侧面板。
我要在侧面板中显示在 A B 或 C 中定义的表单,这样,当人们创建额外的组件时,他们可以定义将显示在侧面板中的选项表单。
对于静态设置,我可以创建一个服务以将数据从侧面板传入和传出当前的活动组件(A,B或C),但是我认为EmbeddedViewRef和模板可以很好地扩展,并且当应用程序由新组件 D 扩展时,不需要编辑侧面板或数据传递服务。
app.component.html
<side-panel>
</side-panel>
<router-outlet></outlet>
在侧面板组件中,我要渲染选项,该选项根据路由器插座中显示的组件而改变
a.component.html
<div>
{{option1 * 10}}
</div>
<ng-template #options>
<input type="number" [(ngModel)]="option1">
</ng-template>
我希望#options模板显示在A组件的同级面板中。
渲染模板时,您可以注入上下文对象,但我希望上下文与A的上下文相同,以便在侧面板中选择的更改和选项会影响A组件。
对于我应该阅读哪些概念的任何帮助,将不胜感激。
答案 0 :(得分:1)
不确定我是否正确理解了您想要的内容,但我认为您可以使用内容投影来使用<ng-content>
标签在侧面板组件中投影组件A,B或C。
// side-panel component:
<ng-content></ng-content>
// app component
<app-side-panel>
<router-outlet></router-outlet>
</app-side-panel>
这是一个完整的示例:https://stackblitz.com/edit/angular-rzh9cw
更新: 再次阅读您的问题,我认为您遇到的是一个状态管理问题:
我希望#options模板显示在A组件的同级面板中。
<ng-template #options>
<input type="number" [(ngModel)]="option1">
</ng-template>
由于#options
模板会从组件的内部和外部影响组件A的属性,因此您需要将#options
定义为单独的组件,以便可以在两个地方重复使用: / p>
选项组件:
<input #input type="number" (change)="changeOption(input.value)">
组件A:
<div>
{{option1 * 10}}
</div>
<app-options></app-options>
侧面板组件:
<app-options></app-options>
现在,为了使OptionsComponent在组件A中进行更改,您可以使用一项服务来存储要更改的这些选项的状态,并在整个应用程序中共享,这样组件A,B或C可以侦听它并做出相应的反应:
选项服务:
@Injectable({ providedIn: 'root' })
class OptionsService {
private options$ = new BehaviorSubject({
option1: 1,
option2: 'on',
option3: 'blue'
});
public options: Observable<Options>;
constructor() {
this.options = this.options$.asObservable();
}
public changeOptions(options: Options) {
this.options$.next(options);
}
}
选项组件(使用OptionsService触发更改):
constructor(private optionsService: OptionsService) {}
public changeOption(value): void {
this.optionsService.changeOptions({
option1: value,
option2: 'off',
option3: 'red'
});
}
最后,组件A可以订阅以下更改:
constructor(private optionsService: OptionsService) {}
public ngOnInit() {
this.optionsService.options.subscribe((options: Options) => {
console.log(options);
this.option1 = options.option1;
});
}