I have a component A
and 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>
Component B
does not contain component A
or way around
<componentA></componentA>
<componentB></componentB>
I tried to wrap <div class="A1"></div>
in to ng-template
and then in componentB
I was querying for that, but it is always undefined
:
@ViewChild('templ') templ: TemplateRef<any>;
Then I realized that @ViewChild
is to query component children, so how would you query and render <ng-template>
it it is not child component?
Have a look in to this awesome sideNav sample by Alex Rickabaugh, that demoing exactly what you need.
Based on that you need to define an ng-container
in your ComponentA
. Then you need to mark the piece of your ComponentB
with a custom directive and there is a service that connecting ComponentA
and ComponentB
:
<div class="A1"><div>
<div class="A2" *leftNav >
<h3>Content</h3>
</div>
Directive:
@Directive({
selector: '[leftNav]',
})
export class LeftNavDirective implements OnInit {
constructor(private leftNav: LeftNav, private ref: TemplateRef<any>) {}
ngOnInit(): void {
this.leftNav.setContents(this.ref);
}
}
Service:
@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);
}
}
Finally in your ComponentB
you have to subscribe for your <div class="A1"> ... <div>
thing on 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);
});
}