디렉티브를 조각으로 바꾸기

당신은 아마 이것을해서는 안됩니다. 나쁜 생각입니다. 어쨌든 여기에 코드가 있습니다.

@Directive()
export class Fragment {
  nativeElement;
  comment;
  childNodes

  constructor() {
    this.nativeElement = inject(ElementRef).nativeElement;
    this.comment = document.createComment(
      ` ${Object.getPrototypeOf(this).constructor.name} `
    );
  }

  ngAfterViewInit() {
    const { nativeElement, comment } = this;
    const parent = nativeElement.parentElement;
    this.childNodes = Array.from(nativeElement.childNodes)
    parent.insertBefore(comment, nativeElement);
    for (const node of this.childNodes) {
      parent.insertBefore(node, nativeElement);
    }
    nativeElement.remove();
  }

  ngOnDestroy() {
    this.comment.remove();
    for (const node of this.childNodes) {
      node.remove()
    }
  }
}


이것은 디렉티브의 호스트 요소를 그 안에 있는 것으로 대체합니다. 그것은 심지어 뒤에 멋진 작은 코멘트를 남깁니다.

사용 방법을 확인하기 위해 템플릿의 값을 전달할 공급자를 만들어 보겠습니다.

@Directive({
  selector: 'MyProvider',
})
export class MyProvider extends Fragment {
  @Input() value;
}


여기서는 렌더링된 DOM 요소와 구분하기 위해 TitleCase를 사용하고 있습니다. Angular 선택자는 대소문자를 구분합니다.

이제 지시문을 가져와 템플릿에서 사용할 수 있습니다.

<MyProvider [value]="name">
  <hello></hello>
</MyProvider>

hello 구성 요소는 공급자를 주입하여 해당 값을 읽을 수 있습니다.

@Component({
  selector: 'hello',
  template: `<h1>Hello {{provider.value}}!</h1>`,
  styles: [`h1 { font-family: Lato; }`],
})
export class HelloComponent {
  provider = inject(MyProvider);
}


See it in action on StackBlitz

DOM을 보면 호스트 요소가 HTML 주석으로 대체된 것을 볼 수 있습니다.



이것은 좋은 생각입니까?



아마 아닐 겁니다. 그다지 효율적이지 않은 방식으로 <ng-container>에 약간의 설탕을 추가하는 것뿐입니다. 내가 모르는 다른 부작용이있을 수 있습니다.

유스 케이스를 생각할 수 있습니까?

좋은 웹페이지 즐겨찾기