fix(ivy): support projecting containers created by query reads (#31790)
PR Close #31790
This commit is contained in:
parent
54ef63b0f4
commit
0e68c7edf9
|
@ -99,6 +99,13 @@ export function refreshDescendantViews(lView: LView) {
|
||||||
refreshContentQueries(tView, lView);
|
refreshContentQueries(tView, lView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We must materialize query results before child components are processed
|
||||||
|
// in case a child component has projected a container. The LContainer needs
|
||||||
|
// to exist so the embedded views are properly attached by the container.
|
||||||
|
if (!creationMode || tView.staticViewQueries) {
|
||||||
|
executeViewQueryFn(RenderFlags.Update, tView, lView[CONTEXT]);
|
||||||
|
}
|
||||||
|
|
||||||
refreshChildComponents(tView.components);
|
refreshChildComponents(tView.components);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1752,10 +1759,6 @@ export function checkView<T>(hostView: LView, component: T) {
|
||||||
creationMode && executeViewQueryFn(RenderFlags.Create, hostTView, component);
|
creationMode && executeViewQueryFn(RenderFlags.Create, hostTView, component);
|
||||||
executeTemplate(hostView, templateFn, getRenderFlags(hostView), component);
|
executeTemplate(hostView, templateFn, getRenderFlags(hostView), component);
|
||||||
refreshDescendantViews(hostView);
|
refreshDescendantViews(hostView);
|
||||||
// Only check view queries again in creation mode if there are static view queries
|
|
||||||
if (!creationMode || hostTView.staticViewQueries) {
|
|
||||||
executeViewQueryFn(RenderFlags.Update, hostTView, component);
|
|
||||||
}
|
|
||||||
safeToRunHooks = true;
|
safeToRunHooks = true;
|
||||||
} finally {
|
} finally {
|
||||||
leaveView(oldView, safeToRunHooks);
|
leaveView(oldView, safeToRunHooks);
|
||||||
|
|
|
@ -1625,6 +1625,40 @@ describe('ViewContainerRef', () => {
|
||||||
'<child-with-selector><p class="a"><header vcref="">blah</header><span>bar</span></p><p class="b"></p></child-with-selector>');
|
'<child-with-selector><p class="a"><header vcref="">blah</header><span>bar</span></p><p class="b"></p></child-with-selector>');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should create embedded view when ViewContainerRef is inside projection', () => {
|
||||||
|
@Component({
|
||||||
|
selector: 'content-comp',
|
||||||
|
template: '<ng-content></ng-content>',
|
||||||
|
})
|
||||||
|
class ContentComp {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'my-comp',
|
||||||
|
template: `
|
||||||
|
<content-comp>
|
||||||
|
<div #target></div>
|
||||||
|
</content-comp>
|
||||||
|
|
||||||
|
<ng-template #source>My Content</ng-template>
|
||||||
|
`
|
||||||
|
})
|
||||||
|
class MyComp {
|
||||||
|
@ViewChild('source', {static: true})
|
||||||
|
source !: TemplateRef<{}>;
|
||||||
|
|
||||||
|
@ViewChild('target', {read: ViewContainerRef, static: true})
|
||||||
|
target !: ViewContainerRef;
|
||||||
|
|
||||||
|
ngOnInit() { this.target.createEmbeddedView(this.source); }
|
||||||
|
}
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({declarations: [MyComp, ContentComp]});
|
||||||
|
const fixture = TestBed.createComponent(MyComp);
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(fixture.debugElement.nativeElement.innerHTML).toContain('My Content');
|
||||||
|
});
|
||||||
|
|
||||||
it('should not project the ViewContainerRef content, when the host does not match a selector',
|
it('should not project the ViewContainerRef content, when the host does not match a selector',
|
||||||
() => {
|
() => {
|
||||||
@Component({
|
@Component({
|
||||||
|
|
Loading…
Reference in New Issue