gpt4 book ai didi

angular - 如何访问父组件中提供的 TemplateRef 中的服务?

转载 作者:行者123 更新时间:2023-12-05 05:36:02 25 4
gpt4 key购买 nike

最近我有一个任务,我需要将一个 TemplateRef 传递给组件,它提供一些服务,比如 SomeService。在该模板中,我使用了一个注入(inject)服务 SomeService 的指令。我最终遇到了 NullInjectorError

所以我的问题是如何在组件中而不是在 ViewContent 中获取服务。

这是我正在尝试做的事情的最小表示。假设所有组件和指令都在同一个模块中声明。

根组件。这里发生的所有事情是我将模板引用传递给应用程序组件并使用模板内的指令。

@Component({
selector: 'root-component',
template: `
<app-component [itemTemplate]="template"></app-component>

<ng-template #template >
<div testDirective>hello</div>
</ng-template>
`
})
export class RootComponent {
}

应用组件。这里我提供SomeService

@Component({
selector: 'app-component',
template: `
<ng-container [ngTemplateOutlet]="itemTemplate"></ng-container>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [
SomeService // <-- HERE IS THE SERVICE THAT I'M TRYING TO INJECT INTO DIRECTIVE
],
})
export class AppComponent {
@Input()
itemTemplate: TemplateRef<unknown> | null = null;

constructor(
) {

}
}

测试指令

@Directive({
selector: '[testDirective]'
})
export class TestDirective {
constructor(
private _someService: SomeService // <-- THIS CAUSE AN NullInjectorError
) {
}
}

没有必要显示 SomeService 的实现,因为它只是一个常规服务。

如果有什么不清楚的地方,我深表歉意,这是我在 StackOverflow 上的第一个问题

Stackblitz here

最佳答案

Angular v14 解决方案

使用 Angular 14,您可以将 injector 传递给 ngTemplateOutlet 指令。通过这种方式,将在 ng-container 中呈现的 embeddedView 将引用当前组件注入(inject)器树(并指向注入(inject)的 SomeService 组件级别的提供程序。

@Component({
selector: 'app-component',
template: `
<ng-container
[ngTemplateOutlet]="itemTemplate"
[ngTemplateOutletInjector]="injector">
</ng-container>
`,
...
})
export class AppComponent {
@Input()
itemTemplate: TemplateRef<unknown> | null = null;

constructor(
public readonly injector: Injector
) {}
}


Angular v13 或更少

您必须对模板的传递方式进行一些更改。而不是将 TemplateRef 作为 Input 绑定(bind)传递。将该 ng-template 作为内容投影传递。

@Component({
selector: 'root-component',
template: `
<app-component>
<!--Pass template as content projection-->
<ng-template #template>
<div testDirective>hello</div>
</ng-template>
</app-component>
`,
})
export class RootComponent {}

然后 AppComponent 可以使用 @ContentChild 来查找嵌入的 View (ng-template)检查 #template 模板变量。就是这样。 itemTemplate 将在 ContentChild 查询检索到结果后立即填充。轰隆🎉🎉

@Component({
selector: 'app-component',
...
})
export class AppComponent {
// VVVV change here to ContentChild
@ContentChild('template')
itemTemplate: TemplateRef<unknown>;
}

在这种情况下,模板是 AppComponent 的一部分,注入(inject)器树正确解析了 SomeService

Demo

关于angular - 如何访问父组件中提供的 TemplateRef 中的服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73376762/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com