fix(ivy): merged host bindings functions should take superclass hostVars into account (#27013)
PR Close #27013
This commit is contained in:
parent
2f36a9591d
commit
552836ebf0
|
@ -76,6 +76,7 @@ export function InheritDefinitionFeature(definition: DirectiveDef<any>| Componen
|
||||||
superHostBindings(directiveIndex, elementIndex);
|
superHostBindings(directiveIndex, elementIndex);
|
||||||
prevHostBindings(directiveIndex, elementIndex);
|
prevHostBindings(directiveIndex, elementIndex);
|
||||||
};
|
};
|
||||||
|
(definition as any).hostVars += superDef.hostVars;
|
||||||
} else {
|
} else {
|
||||||
definition.hostBindings = superHostBindings;
|
definition.hostBindings = superHostBindings;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Inject, InjectionToken} from '../../src/core';
|
import {Inject, InjectionToken} from '../../src/core';
|
||||||
import {ComponentDef, DirectiveDef, InheritDefinitionFeature, NgOnChangesFeature, ProvidersFeature, RenderFlags, defineBase, defineComponent, defineDirective, directiveInject, element} from '../../src/render3/index';
|
import {ComponentDef, DirectiveDef, InheritDefinitionFeature, NgOnChangesFeature, ProvidersFeature, RenderFlags, bind, defineBase, defineComponent, defineDirective, directiveInject, element, elementProperty, load} from '../../src/render3/index';
|
||||||
|
|
||||||
import {ComponentFixture, createComponent} from './render_util';
|
import {ComponentFixture, createComponent} from './render_util';
|
||||||
|
|
||||||
describe('InheritDefinitionFeature', () => {
|
describe('InheritDefinitionFeature', () => {
|
||||||
|
@ -299,36 +300,61 @@ describe('InheritDefinitionFeature', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should compose hostBindings', () => {
|
it('should compose hostBindings', () => {
|
||||||
const log: Array<[string, number, number]> = [];
|
let subDir !: SubDirective;
|
||||||
|
|
||||||
class SuperDirective {
|
class SuperDirective {
|
||||||
|
id = 'my-id';
|
||||||
|
|
||||||
static ngDirectiveDef = defineDirective({
|
static ngDirectiveDef = defineDirective({
|
||||||
type: SuperDirective,
|
type: SuperDirective,
|
||||||
selectors: [['', 'superDir', '']],
|
selectors: [['', 'superDir', '']],
|
||||||
hostBindings: (directiveIndex: number, elementIndex: number) => {
|
hostBindings: (directiveIndex: number, elementIndex: number) => {
|
||||||
log.push(['super', directiveIndex, elementIndex]);
|
const instance = load(directiveIndex) as SuperDirective;
|
||||||
|
elementProperty(elementIndex, 'id', bind(instance.id));
|
||||||
},
|
},
|
||||||
|
hostVars: 1,
|
||||||
factory: () => new SuperDirective(),
|
factory: () => new SuperDirective(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class SubDirective extends SuperDirective {
|
class SubDirective extends SuperDirective {
|
||||||
|
title = 'my-title';
|
||||||
|
|
||||||
static ngDirectiveDef = defineDirective({
|
static ngDirectiveDef = defineDirective({
|
||||||
type: SubDirective,
|
type: SubDirective,
|
||||||
selectors: [['', 'subDir', '']],
|
selectors: [['', 'subDir', '']],
|
||||||
hostBindings: (directiveIndex: number, elementIndex: number) => {
|
hostBindings: (directiveIndex: number, elementIndex: number) => {
|
||||||
log.push(['sub', directiveIndex, elementIndex]);
|
const instance = load(directiveIndex) as SubDirective;
|
||||||
|
elementProperty(elementIndex, 'title', bind(instance.title));
|
||||||
},
|
},
|
||||||
factory: () => new SubDirective(),
|
hostVars: 1,
|
||||||
|
factory: () => subDir = new SubDirective(),
|
||||||
features: [InheritDefinitionFeature]
|
features: [InheritDefinitionFeature]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const subDef = SubDirective.ngDirectiveDef as DirectiveDef<any>;
|
|
||||||
|
|
||||||
subDef.hostBindings !(1, 2);
|
const App = createComponent('app', (rf: RenderFlags, ctx: any) => {
|
||||||
|
if (rf & RenderFlags.Create) {
|
||||||
|
element(0, 'div', ['subDir', '']);
|
||||||
|
}
|
||||||
|
}, 1, 0, [SubDirective]);
|
||||||
|
|
||||||
expect(log).toEqual([['super', 1, 2], ['sub', 1, 2]]);
|
const fixture = new ComponentFixture(App);
|
||||||
|
const divEl = fixture.hostElement.querySelector('div') as HTMLElement;
|
||||||
|
|
||||||
|
expect(divEl.id).toEqual('my-id');
|
||||||
|
expect(divEl.title).toEqual('my-title');
|
||||||
|
|
||||||
|
subDir.title = 'new-title';
|
||||||
|
fixture.update();
|
||||||
|
expect(divEl.id).toEqual('my-id');
|
||||||
|
expect(divEl.title).toEqual('new-title');
|
||||||
|
|
||||||
|
subDir.id = 'new-id';
|
||||||
|
fixture.update();
|
||||||
|
expect(divEl.id).toEqual('new-id');
|
||||||
|
expect(divEl.title).toEqual('new-title');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should compose viewQuery', () => {
|
it('should compose viewQuery', () => {
|
||||||
|
|
|
@ -1231,7 +1231,6 @@ import {NgModelCustomComp, NgModelCustomWrapper} from './value_accessor_integrat
|
||||||
|
|
||||||
describe('validation directives', () => {
|
describe('validation directives', () => {
|
||||||
|
|
||||||
fixmeIvy('RequiredValidator provided instead of CheckboxRequiredValidator') &&
|
|
||||||
it('required validator should validate checkbox', fakeAsync(() => {
|
it('required validator should validate checkbox', fakeAsync(() => {
|
||||||
const fixture = initTest(NgModelCheckboxRequiredValidator);
|
const fixture = initTest(NgModelCheckboxRequiredValidator);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
Loading…
Reference in New Issue