angular2 ng-template在一个单独的文件中

Pra*_*A.K 11 typescript ng-template angular

angular2如何使用来自不同文件的ng-template?当我将ng-template放在我使用它的同一个HTML中时,但是当我将ng-template移动到一个单独的文件中时,它将无法工作.有没有办法将ng-template移动到自己的文件中并在不同的html文件中使用它?

INFO-message.html

<ng-template #messageTemplate>
    Hi
</ng-template>

<ng-container *ngTemplateOutlet="messageTemplate;"></ng-container>
Run Code Online (Sandbox Code Playgroud)

以上工作正常,因为ng-template和用法在同一个文件中

消息template.html

<ng-template #messageTemplate>
    Hi
</ng-template>
Run Code Online (Sandbox Code Playgroud)

INFO-message.html

<ng-container *ngTemplateOutlet="messageTemplate;"></ng-container>
Run Code Online (Sandbox Code Playgroud)

这不起作用.有没有办法使用"messageTemplate",它位于另一个html中的单独文件中(例如:info-message.html)

提前致谢.

pet*_*eld 5

这种行为可以通过“门户”来实现。这是 Angular 应用程序中一种有用且相当常见的模式。例如,您可能有一个位于顶级应用程序级别附近的全局侧边栏出口,然后子组件可能会指定一个 local <ng-template/>,作为其整体模板的一部分,在此位置呈现。

请注意,虽然<ng-template/>可以在定义所需出口的文件外部定义 ,但仍然需要将某些组件<ng-template/>的模板放在内部。这可以是一个极简的组件,它只负责包装,但它同样可以是一个复杂的组件,其中感兴趣的部分只占很小的一部分。<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;
  }
}
Run Code Online (Sandbox Code Playgroud)

它使用三个部分工作:

  • “门户”指令。这存在于所需<ng-template/>的位置,并将内容应呈现的插座的名称作为输入。
  • “门户网站”指令。这存在于一个插座上,例如 an <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>
Run Code Online (Sandbox Code Playgroud)

一般来说,重新发明轮子并不是一个好主意,尽管已经有经过充分测试、记录和稳定的实现可用。该角CDK提供这样的实现,我会建议使用一个,而不是你自己在实践中。


blu*_*ray -1

您可以使用类似的东西(模板是从另一个组件使用的):

@Component(
    template: '<ng-container *ngTemplateOutlet="infoMessage.template;"></ng-container>'
)
export class MessageTemplate {
    infoMessage: InfoMessage;    
}

@Component(
    ....
)
export class InfoMessage{    
    @ContentChild('columnTemplate') template: TemplateRef<any>;

    constructor(private messageTemplate: MessageTemplate) {
        messageTemplate.infoMessage = this;
    }
}
Run Code Online (Sandbox Code Playgroud)