Как визуализировать часть компонента A в компоненте B

У меня есть компонент A а также B

<div class="A">
    <div class="A1"></div>
    <div class="A2"></div>
</div>

<div class="B">
    <!--want to display <div class="A1"></div> here-->
</div>

Составная часть B не содержит компонент A или наоборот

<componentA></componentA>
<componentB></componentB>

Я пытался завернуть <div class="A1"></div> в к ng-template а затем в componentB Я просил об этом, но это всегда undefined:

@ViewChild('templ') templ: TemplateRef<any>;

Тогда я понял, что @ViewChild это запросить дочерние компоненты, так как бы вы запросить и визуализировать <ng-template> это не дочерний компонент?

3 ответа

Решение

Взгляните на этот потрясающий образец sideNav от Alex Rickabaugh, который демонстрирует именно то, что вам нужно.

Исходя из этого, вам нужно определить ng-container в вашем ComponentA, Затем вам нужно отметить кусок вашего ComponentB с пользовательской директивой и есть сервис, который соединяет ComponentA а также ComponentB:

<div class="A1"><div>
<div class="A2" *leftNav >
  <h3>Content</h3>
</div>

Директива:

@Directive({
  selector: '[leftNav]',
})
export class LeftNavDirective implements OnInit {
  constructor(private leftNav: LeftNav, private ref: TemplateRef<any>) {}

  ngOnInit(): void {
    this.leftNav.setContents(this.ref);
  }
}

Обслуживание:

@Injectable()
export class LeftNav {
  private _state = new BehaviorSubject<TemplateRef<any>|null>(null);
  readonly contents = this._state.asObservable();

  setContents(ref: TemplateRef<any>): void {
    this._state.next(ref);
  }

  clearContents(): void {
    this._state.next(null);
  }
}

Наконец в вашем ComponentB Вы должны подписаться на свой <div class="A1"> ... <div> вещь на ngAfterViewInit:

ngAfterViewInit(): void {
    this
      .leftNav
      .contents
      .subscribe(ref => {
        if (this._current !== null) {
          this._current.destroy();
          this._current = null;
        }
        if (ref === null) {
          return;
        }
        this._current = this.vcr.createEmbeddedView(ref);
    });
  }

PS есть видео и слайды на эту тему.

Компонент рендеринга AШаблон как содержание компонента B

<ComponentB>
   <ComponentA></ComponentA>
</ComponentB>

Внутренний шаблон componentB визуализировать "контент" (в данном случае ComponentAшаблон)

ComponentB.component.html

<ng-content> </ng-content>

Чтобы получить доступ к предоставленным ComponentA в ComponentB использование ContentChild

@ContentChild(ComponentA) footer: componentA;

Вы могли бы создать общий ng-template в родительском компоненте и передать его templateRef дочерний компонент в Input привязки компонента. Позже внутренний компонент заполнит привязки шаблона для этого шаблона.

Что это значит добавить @Input a1: TemplateRef<any>; внутри как компонента, так и давайте положить ниже ng-template в родительском компоненте родителя компонента A & B (в основном они имеют одного и того же родителя).

<ng-template #a1>
    <div class="A1">
       {{item.Description}}
    </div>
</ng-tmeplate>

Компонент А шаблон

<div class="A">
    <ng-container 
       *ngTemplateOutlet="a1;context:{item: valueFromComponentA}">
    </ng-container>
    <div class="A2"></div>
</div>

Компонент B temlpate

<div class="B">
    <ng-container 
       *ngTemplateOutlet="a1;context:{item: valueFromComponentB}">
    </ng-container>
</div>
Другие вопросы по тегам