показать в другом компоненте - PullRequest
0 голосов
/ 07 мая 2020

У меня 2 компонента.

.html родительского компонента, это код:

<div class="space">
    <ng-container *ngFor="let item of items">
        <ng-container [ngTemplateOutlet]="itemTemplate" [ngTemplateOutletContext]="{item: item}">
        </ng-container>
    </ng-container>
</div>

    <ng-template #itemTemplate let-item="item">
        <div class="host">
            <img class='card-img-top'
                src={{item.image}}
                >
            <p>&nbsp;</p>
            <h6 class="title">{{item.projectTitle}}</h6>
            <hr>

            <ng-container *ngIf="item.type=='inactive'">
                <button id="inactive"
                    class="btn btn-sm btn-warning py-0 custom-button text-uppercase">{{item.type}}</button>
            </ng-container>
        </div>
    </ng-template>

Весь код начиная со строки: <ng-template #itemTemplate let-item="item">

Это необходимо показать в .html дочернего компонента.

Это. ts родительского компонента

import { AfterViewInit, Component, ComponentFactoryResolver, ViewChild, ViewContainerRef, OnInit, TemplateRef, Input, ContentChild } from '@angular/core';
import listProjects from './projects.json';
import { ChildComponent } from './child.component';

@Component({
  selector: 'parent-view',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.scss'],
})
export class ParentComponent {
  public items: any = listProjects;
  @ContentChild('itemTemplate', { read: TemplateRef }) itemTemplate: ViewContainerRef;

Как можно отобразить <ng-template #itemTemplate let-item="item"> в другом компоненте?

Ответы [ 2 ]

0 голосов
/ 09 мая 2020

Решение этой проблемы:

Файл: projects-tile-view-components.ts

export class ProjectsTileViewComponent {
  @ViewChild('tileViewItems', { static: true }) tileViewItemTemplate: TileViewComponent;
  public items = listProjects;
  public type = 'etb';
  constructor() {}

  addItems(e) {
    if (this.type === 'osd') {
      this.type = 'etb';
    } else {
      this.type = 'osd';
    }
  }
}

файл projects-tile-view-components.html

<lib-tile-view [items]="items" #tileViewItems>
    <ng-template #tileViewItem let-item>
        <div [ngSwitch]="type">
            <lib-osd-tile-view-item [item]="item" *ngSwitchCase="'osd'"></lib-osd-tile-view-item>
            <lib-osd-tile-view-item [item]="item" *ngSwitchDefault></lib-osd-tile-view-item>
            <lib-etb-tile-view-item [item]="item" *ngSwitchCase="'etb'"></lib-etb-tile-view-item>
        </div>
    </ng-template>
</lib-tile-view>

файл view-item.ts (интерфейс )

export interface ViewItem {
  item: any;
}

файл tile-view-components.html

<div>
    <ng-container *ngFor="let item of items">
        <ng-container *ngTemplateOutlet="tileViewItemTemplate; context: {$implicit: item}">
        </ng-container> 
    </ng-container>
</div>

файл tile-view-item.components.ts

@Component({
  selector: 'lib-tile-view',
  templateUrl: './tile-view.component.html',
  styleUrls: ['./tile-view.component.scss'],
})
export class TileViewComponent {
  @Input()
  public items: any;
  @ContentChild('tileViewItem', { static: true }) tileViewItemTemplate;
}

файл osd-tile-view-components.ts

@Component({
  selector: 'lib-osd-tile-view-item',
  templateUrl: './osd-tile-view-item.component.html',
  styleUrls: ['./osd-tile-view-item.component.scss'],
})
export class OsdTileViewItemComponent implements ViewItem {
  @Input() item: any;
  public projectView() {
    alert('show project');
  }
}

файл osd-tile-view-item.components.html

<div class="host" fxFlex="0 1 calc(100% - 32px)" fxFlex.lt-md="0 1 calc(100% - 32px)" fxFlex.lt-sm="100%" (click) = 'projectView()'>
    <img class='img-fluid img-thumbnail' src={{item?.image}} alt='logo nih'>
    <p>&nbsp;</p>
    <h6 class="title">{{item?.projectTitle}}</h6>
    <p class="small"><span class="text-muted small text-uppercase">ZIA ID
            Number:</span>{{item?.number}}</p>

</div>

Спасибо за помощь

0 голосов
/ 07 мая 2020

Вам нужно поделиться этим TemplateRef в службе (если вы хотите иметь доступ к каждому компоненту в своем приложении), а затем в другом компоненте вы можете прочитать эту ссылку и что-то с ней сделать - потому что, если вы хотите передать эта ссылка только на дочерний, тогда вы можете использовать @Input() в дочернем компоненте, но если он должен быть доступен для всех компонентов, вам необходимо создать сервис.

service:

@Injectable({
  providedIn: 'root'
})
export class TemplateService {
  someTemplate: TemplateRef<any>;
}

componentA:

@Component({
  selector: 'parent-view',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.scss'],
})
export class ParentComponent {
  public items: any = listProjects;
  @ViewChild('itemTemplate', { read: TemplateRef }) set itemTemplate(value) {
    this.ts.someTemplate = value;
  }
  construtor(private ts: TemplateService) {}
}

то в любом другом компоненте вы можете прочитать эту ссылку на шаблон

componentB:

@Component({
  selector: 'component-b',
  templateUrl: './component-b.component.html',
  styleUrls: ['./component-b.component.scss'],
})
export class ComponentBComponent {
  get itemTemplateReference() {
    return this.ts.itemTemplate;
  }
  construtor(private ts: TemplateService) {}
}

.html componentB

<ng-container [ngTemplateOutlet]="itemTemplateReference"></ng-container>

И он должен отобразить то же самое <ng-template>

...