Angular - 在兄弟组件中渲染模板
Angular - Render a template in a sibling component
我不知道如何完成这个:
我想在组件中定义一个将由同级组件呈现的部分,但使用原始组件的上下文:
想象以下组件:A、B、C 和 side-panel.
在侧面板中,我想显示在 A B[=47= 中 defined 的表单] 或 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 组件。
任何关于我应该阅读哪些概念的帮助将不胜感激。
更新:
Angular CDK 门户正是解决了这个问题。它们允许在另一个地方呈现组件的模板 - 一个 portalHost。
https://material.angular.io/cdk/portal/overview
不确定我是否正确理解了您的需求,但我认为您可以使用内容投影来使用 <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
更新:
再次阅读您的问题,我认为您遇到的是状态管理问题:
I would like the #options template to be displayed in the side-panel component which is a sibling of A component.
<ng-template #options>
<input type="number" [(ngModel)]="option1">
</ng-template>
由于#options
模板会从组件内部和组件外部影响组件A的属性,因此您需要将#options
定义为一个单独的组件,以便您可以在两个地方重用它:
选项组件:
<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);
}
}
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;
});
}
我不知道如何完成这个:
我想在组件中定义一个将由同级组件呈现的部分,但使用原始组件的上下文: 想象以下组件:A、B、C 和 side-panel.
在侧面板中,我想显示在 A B[=47= 中 defined 的表单] 或 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 组件。
任何关于我应该阅读哪些概念的帮助将不胜感激。
更新:
Angular CDK 门户正是解决了这个问题。它们允许在另一个地方呈现组件的模板 - 一个 portalHost。 https://material.angular.io/cdk/portal/overview
不确定我是否正确理解了您的需求,但我认为您可以使用内容投影来使用 <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
更新: 再次阅读您的问题,我认为您遇到的是状态管理问题:
I would like the #options template to be displayed in the side-panel component which is a sibling of A component.
<ng-template #options>
<input type="number" [(ngModel)]="option1">
</ng-template>
由于#options
模板会从组件内部和组件外部影响组件A的属性,因此您需要将#options
定义为一个单独的组件,以便您可以在两个地方重用它:
选项组件:
<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);
}
}
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;
});
}