angular2如何使用不同文件中的ng-template?当我将 ng-template 放在我使用的同一个 HTML 中时,它可以工作,但是当我将 ng-template 移动到一个单独的文件中时,它就无法工作。有没有办法将 ng-template 移动到自己的文件中并在不同的 html 文件中使用它?
信息消息.html
<ng-template #messageTemplate>
Hi
</ng-template>
<ng-container *ngTemplateOutlet="messageTemplate;"></ng-container>
上面工作正常,因为 ng-template 和用法位于同一个文件中
消息模板.html
<ng-template #messageTemplate>
Hi
</ng-template>
信息消息.html
<ng-container *ngTemplateOutlet="messageTemplate;"></ng-container>
这是行不通的。有没有办法使用“消息模板”它位于另一个 html 内的单独文件中(例如:info-message.html)
提前致谢。
此行为可以通过“门户”来实现。这是 Angular 应用程序中一种有用且相当常见的模式。例如,您可能有一个位于顶部应用程序级别附近的全局侧边栏出口,然后子组件可以指定本地<ng-template/>
,作为其整体模板的一部分,将在此位置呈现。
请注意,虽然<ng-template/>
可以在定义所需插座的文件外部定义,但仍然需要放置<ng-template/>
的模板内some成分。这可以是一个极简组件,仅负责包装<ng-template/>
,但是它同样可能是一个复杂的组件,其中<ng-template/>
兴趣只占很小的一部分。
此代码说明了门户的一种可能的基本实现。
@Directive({
selector: '[appPortal]'
})
export class PortalDirective implements AfterViewInit {
@Input() outlet: string;
constructor(private portalService: PortalService, private templateRef: TemplateRef<any>) {}
ngAfterViewInit(): void {
const outlet: PortalOutletDirective = this.portalService.outlets[this.outlet];
outlet.viewContainerRef.clear();
outlet.viewContainerRef.createEmbeddedView(this.templateRef);
}
}
@Directive({
selector: '[appPortalOutlet]'
})
export class PortalOutletDirective implements OnInit {
@Input() appPortalOutlet: string;
constructor(private portalService: PortalService, public viewContainerRef: ViewContainerRef) {}
ngOnInit(): void {
this.portalService.registerOutlet(this);
}
}
@Injectable({
providedIn: 'root'
})
export class PortalService {
outlets = new Map<string, PortalOutletDirective>();
registerOutlet(outlet: PortalOutletDirective) {
this.outlets[outlet.appPortalOutlet] = outlet;
}
}
它使用三个部分工作:
- “门户”指令。这生活在所期望的
<ng-template/>
并将应呈现内容的出口的名称作为输入。
- “门户出口”指令。这存在于插座上,例如一个
<ng-container/>
,并定义出口。
- “门户”服务。这是在根级别提供的,并存储对门户出口的引用,以便门户可以访问它们。
对于一些非常简单的事情来说,这似乎需要大量工作,但是一旦管道就位,就很容易(重新)使用。
<div class="container">
<div class="row">
<div class="col-6">
<app-foo></app-foo>
</div>
<div class="col-6">
<ng-container [appPortalOutlet]="'RightPanel'"></ng-container>
</div>
</div>
</div>
// foo.component.html
<h1>Foo</h1>
<ng-template appPortal [outlet]="'RightPanel'">
<h1>RIGHT</h1>
</ng-template>
一般来说,尽管已经有经过充分测试、记录在案且稳定的实现可用,但重新发明轮子并不是一个好主意。这角度 CDK https://material.angular.io/cdk提供这样的实现 https://material.angular.io/cdk/portal我建议在实践中使用那个而不是你自己的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)