如何让Angular组件渲染时直接输出模板内容而非保留组件标签?
Great question! You're looking to render your component's template content without the wrapping <app-test> host element—especially critical for your SSR + external template service workflow. Here's how to achieve this across your target Angular versions:
Angular 6.1.x Implementation
Since Angular 6 doesn't have some of the later version's syntactic sugar, we'll use a combination of template references, Renderer2, and view container manipulation to replace the host element with the component's content:
import { Component, OnInit, ElementRef, Renderer2, ViewContainerRef, TemplateRef, ViewChild } from '@angular/core'; @Component({ selector: 'app-test', template: `<ng-template #componentContent>{{ post_name }}</ng-template>` }) export class PostTestComponent implements OnInit { // Replace with your actual post name value (could be input-bound too!) post_name = "My Sample Post"; @ViewChild('componentContent', { static: true }) contentTemplate: TemplateRef<any>; constructor( private elRef: ElementRef, private renderer: Renderer2, private viewContainerRef: ViewContainerRef ) {} ngOnInit() { // Create an embedded view from our template reference const embeddedView = this.viewContainerRef.createEmbeddedView(this.contentTemplate); // Insert each node from the embedded view before the host element embeddedView.rootNodes.forEach(node => { this.renderer.insertBefore( this.elRef.nativeElement.parentNode, node, this.elRef.nativeElement ); }); // Remove the now-empty host element from the DOM this.renderer.removeChild( this.elRef.nativeElement.parentNode, this.elRef.nativeElement ); } }
How it works:
- We wrap our desired content in an
<ng-template>to get a reference to it - On initialization, we create an embedded view from that template
- We move all nodes from the embedded view directly into the host element's parent, right before the host
- Finally, we delete the host element entirely
This works in SSR because Angular's server-side renderer executes the ngOnInit hook and applies these DOM manipulations to the output HTML.
Angular 7/8 Implementation
Angular 7 and 8 add small improvements that simplify this workflow. You can either use the same approach above (it's fully compatible), or opt for a more concise method using attribute selectors + <ng-container>:
Option 1: Attribute Selector with <ng-container>
This avoids DOM manipulation entirely by using a component that attaches to an attribute instead of an element:
import { Component } from '@angular/core'; @Component({ // Use an attribute selector instead of an element selector selector: '[appTest]', template: '{{ post_name }}' }) export class PostTestComponent { post_name = "My Sample Post"; }
Then use it like this in your parent template:
<ng-container appTest></ng-container>
Why this works:
<ng-container>is a special Angular element that never renders to the DOM- The
[appTest]attribute selector attaches our component's logic to the<ng-container> - The component's template content is rendered directly in place of the
<ng-container>(which doesn't appear in the final HTML)
Option 2: Host Element CSS Hiding (For Non-Strict DOM Requirements)
If your external template service just needs the visual content (and doesn't care about the host element being present in the DOM), you can use CSS to make the host element invisible:
import { Component } from '@angular/core'; @Component({ selector: 'app-test', template: '{{ post_name }}', styles: [`:host { display: contents; }`] }) export class PostTestComponent { post_name = "My Sample Post"; }
The display: contents value tells the browser to treat the host element as if it doesn't exist—its children become direct children of the parent. Note that the host element will still be present in the DOM, but it won't affect layout or rendering.
内容的提问来源于stack exchange,提问作者Steve Kanter

