Angular2 : 래핑 태그 없이 구성요소 렌더링
저는 이것을 할 방법을 찾기 위해 고군분투하고 있습니다.상위 구성 요소에서 템플릿은 다음을 설명합니다.table
그리고 그것들thead
요소, 그러나 대리인이 렌더링합니다.tbody
다음과 같은 다른 구성 요소:
<table>
<thead>
<tr>
<th>Name</th>
<th>Time</th>
</tr>
</thead>
<tbody *ngFor="let entry of getEntries()">
<my-result [entry]="entry"></my-result>
</tbody>
</table>
각 myResult 구성 요소는 자체적으로 렌더링됩니다.tr
태그, 기본적으로 다음과 같습니다.
<tr>
<td>{{ entry.name }}</td>
<td>{{ entry.time }}</td>
</tr>
myResult 구성 요소가 필요하지 않도록 상위 구성 요소에 직접 넣지 않는 이유는 myResult 구성 요소가 실제로 여기에 표시된 것보다 더 복잡하기 때문에 별도의 구성 요소와 파일에 동작을 넣으려고 합니다.
결과적으로 DOM이 불량해 보입니다.나는 이것이 무효이기 때문이라고 믿습니다, 왜냐하면.tbody
다음만 포함할 수 있습니다.tr
요소(MDN 참조), 그러나 생성된(간체화된) DOM은 다음과 같습니다.
<table>
<thead>
<tr>
<th>Name</th>
<th>Time</th>
</tr>
</thead>
<tbody>
<my-result>
<tr>
<td>Bob</td>
<td>128</td>
</tr>
</my-result>
</tbody>
<tbody>
<my-result>
<tr>
<td>Lisa</td>
<td>333</td>
</tr>
</my-result>
</tbody>
</table>
포장 없이 동일한 것을 렌더링할 수 있는 방법이 있습니까?<my-result>
태그, 그리고 여전히 테이블 행 렌더링을 단독으로 책임지는 구성 요소를 사용하는 동안?
를 살펴보았습니다.ng-content
,DynamicComponentLoader
,그ViewContainerRef
하지만 제가 보기에는 해결책을 제시하지 못하는 것 같습니다.
특성 선택기를 사용할 수 있습니다.
@Component({
selector: '[myTd]'
...
})
그런 다음 그것을 사용합니다.
<td myTd></td>
"ViewContainerRef"가 필요하며 my-result 구성 요소 내부에서 다음과 같은 작업을 수행합니다.
.html
:
<ng-template #template>
<tr>
<td>Lisa</td>
<td>333</td>
</tr>
</ng-template>
.ts
:
@ViewChild('template', { static: true }) template;
constructor(
private viewContainerRef: ViewContainerRef
) { }
ngOnInit() {
this.viewContainerRef.createEmbeddedView(this.template);
}
당신은 새로운 CSS를 사용해 볼 수 있습니다.display: contents
다음은 내 도구 모음 scs입니다.
:host {
display: contents;
}
:host-context(.is-mobile) .toolbar {
position: fixed;
/* Make sure the toolbar will stay on top of the content as it scrolls past. */
z-index: 2;
}
h1.app-name {
margin-left: 8px;
}
및 html:
<mat-toolbar color="primary" class="toolbar">
<button mat-icon-button (click)="toggle.emit()">
<mat-icon>menu</mat-icon>
</button>
<img src="/assets/icons/favicon.png">
<h1 class="app-name">@robertking Dashboard</h1>
</mat-toolbar>
및 사용 중:
<navigation-toolbar (toggle)="snav.toggle()"></navigation-toolbar>
속성 선택기는 이 문제를 해결하는 가장 좋은 방법입니다.
그래서 당신의 경우:
<table>
<thead>
<tr>
<th>Name</th>
<th>Time</th>
</tr>
</thead>
<tbody my-results>
</tbody>
</table>
내 친구들
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'my-results, [my-results]',
templateUrl: './my-results.component.html',
styleUrls: ['./my-results.component.css']
})
export class MyResultsComponent implements OnInit {
entries: Array<any> = [
{ name: 'Entry One', time: '10:00'},
{ name: 'Entry Two', time: '10:05 '},
{ name: 'Entry Three', time: '10:10'},
];
constructor() { }
ngOnInit() {
}
}
my-message html
<tr my-result [entry]="entry" *ngFor="let entry of entries"><tr>
내 결과
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: '[my-result]',
templateUrl: './my-result.component.html',
styleUrls: ['./my-result.component.css']
})
export class MyResultComponent implements OnInit {
@Input() entry: any;
constructor() { }
ngOnInit() {
}
}
my-result html
<td>{{ entry.name }}</td>
<td>{{ entry.time }}</td>
작업 스택블리츠를 참조하십시오. https://stackblitz.com/edit/angular-xbbegx
요소에 이 지시어 사용
@Directive({
selector: '[remove-wrapper]'
})
export class RemoveWrapperDirective {
constructor(private el: ElementRef) {
const parentElement = el.nativeElement.parentElement;
const element = el.nativeElement;
parentElement.removeChild(element);
parentElement.parentNode.insertBefore(element, parentElement.nextSibling);
parentElement.parentNode.removeChild(parentElement);
}
}
사용 예:
<div class="card" remove-wrapper>
This is my card component
</div>
그리고 부모 html에서는 평소처럼 카드 요소를 호출합니다. 예:
<div class="cards-container">
<card></card>
</div>
출력은 다음과 같습니다.
<div class="cards-container">
<div class="card" remove-wrapper>
This is my card component
</div>
</div>
요즘의 또 다른 옵션은ContribNgHostModule
패키지에서 사용할 수 있습니다.
모듈을 가져온 후 추가할 수 있습니다.host: { ngNoHost: '' }
당신에게@Component
장식자 및 래핑 요소가 렌더링되지 않습니다.
@Shlomi Aharoni 답변의 개선.일반적으로 Renderer2를 사용하여 DOM을 조작하여 Angular를 루프에 유지하는 것이 좋습니다. 보안(예: XSS 공격) 및 서버 측 렌더링을 포함한 다른 이유 때문입니다.
지시 예제
import { AfterViewInit, Directive, ElementRef, Renderer2 } from '@angular/core';
@Directive({
selector: '[remove-wrapper]'
})
export class RemoveWrapperDirective implements AfterViewInit {
constructor(private elRef: ElementRef, private renderer: Renderer2) {}
ngAfterViewInit(): void {
// access the DOM. get the element to unwrap
const el = this.elRef.nativeElement;
const parent = this.renderer.parentNode(this.elRef.nativeElement);
// move all children out of the element
while (el.firstChild) { // this line doesn't work with server-rendering
this.renderer.appendChild(parent, el.firstChild);
}
// remove the empty element from parent
this.renderer.removeChild(parent, el);
}
}
구성요소 예제
@Component({
selector: 'app-page',
templateUrl: './page.component.html',
styleUrls: ['./page.component.scss'],
})
export class PageComponent implements AfterViewInit {
constructor(
private renderer: Renderer2,
private elRef: ElementRef) {
}
ngAfterViewInit(): void {
// access the DOM. get the element to unwrap
const el = this.elRef.nativeElement; // app-page
const parent = this.renderer.parentNode(this.elRef.nativeElement); // parent
// move children to parent (everything is moved including comments which angular depends on)
while (el.firstChild){ // this line doesn't work with server-rendering
this.renderer.appendChild(parent, el.firstChild);
}
// remove empty element from parent - true to signal that this removed element is a host element
this.renderer.removeChild(parent, el, true);
}
}
이것은 저에게 효과적이며 ExpressionChangedAfterItHasCheckedError 오류를 방지할 수 있습니다.
하위 구성 요소:
@Component({
selector: 'child-component'
templateUrl: './child.template.html'
})
export class ChildComponent implements OnInit {
@ViewChild('childTemplate', {static: true}) childTemplate: TemplateRef<any>;
constructor(
private view: ViewContainerRef
) {}
ngOnInit(): void {
this.view.createEmbeddedView(this.currentUserTemplate);
}
}
상위 구성요소:
<child-component></child-component>
언급URL : https://stackoverflow.com/questions/38716105/angular2-render-a-component-without-its-wrapping-tag
'sourcetip' 카테고리의 다른 글
이클립스에 사용할 수 있는 vim 플러그인은 무엇입니까? (0) | 2023.04.28 |
---|---|
Azure: Azure 앱 서비스를 위한 배포 슬롯 가격 (0) | 2023.04.28 |
NOT IN 절 내부의 NULL 값 (0) | 2023.04.28 |
이클립스 내 자바스크립트 편집기 (0) | 2023.04.28 |
Windows 명령줄에 주석을 달려면 어떻게 해야 합니까? (0) | 2023.04.28 |