fix(ivy): inject attributes for directives on ng-template / ng-container (#25697)
PR Close #25697
This commit is contained in:
parent
0fe708ff82
commit
0386c44acc
|
@ -268,12 +268,12 @@ const componentFactoryResolver: ComponentFactoryResolver = new ComponentFactoryR
|
|||
* @experimental
|
||||
*/
|
||||
export function injectAttribute(attrNameToInject: string): string|undefined {
|
||||
ngDevMode && assertPreviousIsParent();
|
||||
const lElement = getPreviousOrParentNode() as LElementNode;
|
||||
ngDevMode && assertNodeType(lElement, TNodeType.Element);
|
||||
const tElement = lElement.tNode;
|
||||
ngDevMode && assertDefined(tElement, 'expecting tNode');
|
||||
const attrs = tElement.attrs;
|
||||
const lNode = getPreviousOrParentNode();
|
||||
ngDevMode && assertNodeOfPossibleTypes(
|
||||
lNode, TNodeType.Container, TNodeType.Element, TNodeType.ElementContainer);
|
||||
const tNode = lNode.tNode;
|
||||
ngDevMode && assertDefined(tNode, 'expecting tNode');
|
||||
const attrs = tNode.attrs;
|
||||
if (attrs) {
|
||||
for (let i = 0; i < attrs.length; i = i + 2) {
|
||||
const attrName = attrs[i];
|
||||
|
|
|
@ -6,19 +6,19 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ChangeDetectorRef, ElementRef, Host, InjectFlags, Optional, Self, SkipSelf, TemplateRef, ViewContainerRef, defineInjectable} from '@angular/core';
|
||||
import {Attribute, ChangeDetectorRef, ElementRef, Host, InjectFlags, Optional, Self, SkipSelf, TemplateRef, ViewContainerRef, defineInjectable} from '@angular/core';
|
||||
import {RenderFlags} from '@angular/core/src/render3/interfaces/definition';
|
||||
|
||||
import {defineComponent} from '../../src/render3/definition';
|
||||
import {bloomAdd, bloomFindPossibleInjector, getOrCreateNodeInjector, injectAttribute} from '../../src/render3/di';
|
||||
import {NgOnChangesFeature, PublicFeature, defineDirective, directiveInject, injectChangeDetectorRef, injectElementRef, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
|
||||
import {bind, container, containerRefreshEnd, containerRefreshStart, createLNode, createLViewData, createTView, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, enterView, interpolation2, leaveView, projection, projectionDef, reference, template, text, textBinding} from '../../src/render3/instructions';
|
||||
import {bind, container, containerRefreshEnd, containerRefreshStart, createLNode, createLViewData, createTView, element, elementEnd, elementStart, embeddedViewEnd, embeddedViewStart, enterView, interpolation2, leaveView, projection, projectionDef, reference, template, text, textBinding, loadDirective, elementContainerStart, elementContainerEnd} from '../../src/render3/instructions';
|
||||
import {LInjector} from '../../src/render3/interfaces/injector';
|
||||
import {AttributeMarker, TNodeType} from '../../src/render3/interfaces/node';
|
||||
import {LViewFlags} from '../../src/render3/interfaces/view';
|
||||
import {ViewRef} from '../../src/render3/view_ref';
|
||||
|
||||
import {ComponentFixture, createComponent, createDirective, renderComponent, renderToHtml, toHtml} from './render_util';
|
||||
import {ComponentFixture, createComponent, createDirective, renderComponent, toHtml} from './render_util';
|
||||
|
||||
describe('di', () => {
|
||||
describe('no dependencies', () => {
|
||||
|
@ -1207,6 +1207,23 @@ describe('di', () => {
|
|||
|
||||
describe('@Attribute', () => {
|
||||
|
||||
class MyDirective {
|
||||
exists = 'wrong' as string | undefined;
|
||||
myDirective = 'wrong' as string | undefined;
|
||||
constructor(
|
||||
@Attribute('exist') existAttrValue: string|undefined,
|
||||
@Attribute('myDirective') myDirectiveAttrValue: string|undefined) {
|
||||
this.exists = existAttrValue;
|
||||
this.myDirective = myDirectiveAttrValue;
|
||||
}
|
||||
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: MyDirective,
|
||||
selectors: [['', 'myDirective', '']],
|
||||
factory: () => new MyDirective(injectAttribute('exist'), injectAttribute('myDirective'))
|
||||
});
|
||||
}
|
||||
|
||||
it('should inject attribute', () => {
|
||||
let exist = 'wrong' as string | undefined;
|
||||
let nonExist = 'wrong' as string | undefined;
|
||||
|
@ -1224,6 +1241,48 @@ describe('di', () => {
|
|||
expect(nonExist).toEqual(undefined);
|
||||
});
|
||||
|
||||
// https://stackblitz.com/edit/angular-scawyi?file=src%2Fapp%2Fapp.component.ts
|
||||
it('should inject attributes on <ng-template>', () => {
|
||||
let myDirectiveInstance: MyDirective;
|
||||
|
||||
/* <ng-template myDirective="initial" exist="existValue" other="ignore"></ng-template>*/
|
||||
const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
template(
|
||||
0, null, 0, 0, null,
|
||||
['myDirective', 'initial', 'exist', 'existValue', 'other', 'ignore']);
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
myDirectiveInstance = loadDirective(0);
|
||||
}
|
||||
}, 1, 0, [MyDirective]);
|
||||
|
||||
new ComponentFixture(MyApp);
|
||||
expect(myDirectiveInstance !.exists).toEqual('existValue');
|
||||
expect(myDirectiveInstance !.myDirective).toEqual('initial');
|
||||
});
|
||||
|
||||
// https://stackblitz.com/edit/angular-scawyi?file=src%2Fapp%2Fapp.component.ts
|
||||
it('should inject attributes on <ng-container>', () => {
|
||||
let myDirectiveInstance: MyDirective;
|
||||
|
||||
/* <ng-container myDirective="initial" exist="existValue" other="ignore"></ng-container>*/
|
||||
const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) {
|
||||
if (rf & RenderFlags.Create) {
|
||||
elementContainerStart(
|
||||
0, ['myDirective', 'initial', 'exist', 'existValue', 'other', 'ignore']);
|
||||
elementContainerEnd();
|
||||
}
|
||||
if (rf & RenderFlags.Update) {
|
||||
myDirectiveInstance = loadDirective(0);
|
||||
}
|
||||
}, 1, 0, [MyDirective]);
|
||||
|
||||
new ComponentFixture(MyApp);
|
||||
expect(myDirectiveInstance !.exists).toEqual('existValue');
|
||||
expect(myDirectiveInstance !.myDirective).toEqual('initial');
|
||||
});
|
||||
|
||||
// https://stackblitz.com/edit/angular-8ytqkp?file=src%2Fapp%2Fapp.component.ts
|
||||
it('should not inject attributes representing bindings and outputs', () => {
|
||||
let exist = 'wrong' as string | undefined;
|
||||
|
|
Loading…
Reference in New Issue