fix(ivy): inject ViewContainerRef for directives on ng-container (#25617)
PR Close #25617
This commit is contained in:
parent
18f129f536
commit
b00038c847
|
@ -586,7 +586,8 @@ export function getOrCreateContainerRef(di: LInjector): viewEngine_ViewContainer
|
|||
if (!di.viewContainerRef) {
|
||||
const vcRefHost = di.node;
|
||||
|
||||
ngDevMode && assertNodeOfPossibleTypes(vcRefHost, TNodeType.Container, TNodeType.Element);
|
||||
ngDevMode && assertNodeOfPossibleTypes(
|
||||
vcRefHost, TNodeType.Container, TNodeType.Element, TNodeType.ElementContainer);
|
||||
const hostParent = getParentLNode(vcRefHost) !;
|
||||
const lContainer = createLContainer(hostParent, vcRefHost.view, true);
|
||||
const comment = vcRefHost.view[RENDERER].createComment(ngDevMode ? 'container' : '');
|
||||
|
|
|
@ -17,7 +17,9 @@ export function assertNodeType(node: LNode, type: TNodeType) {
|
|||
export function assertNodeOfPossibleTypes(node: LNode, ...types: TNodeType[]) {
|
||||
assertDefined(node, 'should be called with a node');
|
||||
const found = types.some(type => node.tNode.type === type);
|
||||
assertEqual(found, true, `Should be one of ${types.map(typeName).join(', ')}`);
|
||||
assertEqual(
|
||||
found, true,
|
||||
`Should be one of ${types.map(typeName).join(', ')} but got ${typeName(node.tNode.type)}`);
|
||||
}
|
||||
|
||||
function typeName(type: TNodeType): string {
|
||||
|
@ -25,5 +27,6 @@ function typeName(type: TNodeType): string {
|
|||
if (type == TNodeType.Container) return 'Container';
|
||||
if (type == TNodeType.View) return 'View';
|
||||
if (type == TNodeType.Element) return 'Element';
|
||||
if (type == TNodeType.ElementContainer) return 'ElementContainer';
|
||||
return '<unknown>';
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import {NgForOfContext} from '@angular/common';
|
||||
|
||||
import {AttributeMarker, defineComponent, templateRefExtractor} from '../../src/render3/index';
|
||||
import {bind, template, elementEnd, elementProperty, elementStart, getCurrentView, interpolation1, interpolation2, interpolation3, interpolationV, listener, load, nextContext, restoreView, text, textBinding} from '../../src/render3/instructions';
|
||||
import {bind, template, elementEnd, elementProperty, elementStart, getCurrentView, interpolation1, interpolation2, interpolation3, interpolationV, listener, load, nextContext, restoreView, text, textBinding, elementContainerStart, elementContainerEnd} from '../../src/render3/instructions';
|
||||
import {RenderFlags} from '../../src/render3/interfaces/definition';
|
||||
|
||||
import {NgForOf, NgIf, NgTemplateOutlet} from './common_with_def';
|
||||
|
@ -924,5 +924,50 @@ describe('@angular/common integration', () => {
|
|||
expect(fixture.html).toEqual('');
|
||||
});
|
||||
|
||||
it('should allow usage on ng-container', () => {
|
||||
class MyApp {
|
||||
showing = false;
|
||||
static ngComponentDef = defineComponent({
|
||||
type: MyApp,
|
||||
factory: () => new MyApp(),
|
||||
selectors: [['my-app']],
|
||||
consts: 3,
|
||||
vars: 1,
|
||||
/**
|
||||
* <ng-template #tpl>from tpl</ng-template>
|
||||
* <ng-container [ngTemplateOutlet]="showing ? tpl : null"></ng-container>
|
||||
*/
|
||||
template: (rf: RenderFlags, myApp: MyApp) => {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(0, (rf1: RenderFlags) => {
|
||||
if (rf1 & RenderFlags.Create) {
|
||||
text(0, 'from tpl');
|
||||
}
|
||||
}, 1, 0, undefined, undefined, ['tpl', ''], templateRefExtractor);
|
||||
elementContainerStart(2, [AttributeMarker.SelectOnly, 'ngTemplateOutlet']);
|
||||
elementContainerEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
const tplRef = load(1);
|
||||
elementProperty(2, 'ngTemplateOutlet', bind(myApp.showing ? tplRef : null));
|
||||
}
|
||||
},
|
||||
directives: () => [NgTemplateOutlet]
|
||||
});
|
||||
}
|
||||
|
||||
const fixture = new ComponentFixture(MyApp);
|
||||
expect(fixture.html).toEqual('');
|
||||
|
||||
fixture.component.showing = true;
|
||||
fixture.update();
|
||||
expect(fixture.html).toEqual('from tpl');
|
||||
|
||||
fixture.component.showing = false;
|
||||
fixture.update();
|
||||
expect(fixture.html).toEqual('');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue