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);
|
||||
prevHostBindings(directiveIndex, elementIndex);
|
||||
};
|
||||
(definition as any).hostVars += superDef.hostVars;
|
||||
} else {
|
||||
definition.hostBindings = superHostBindings;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
*/
|
||||
|
||||
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';
|
||||
|
||||
describe('InheritDefinitionFeature', () => {
|
||||
|
@ -299,36 +300,61 @@ describe('InheritDefinitionFeature', () => {
|
|||
});
|
||||
|
||||
it('should compose hostBindings', () => {
|
||||
const log: Array<[string, number, number]> = [];
|
||||
let subDir !: SubDirective;
|
||||
|
||||
class SuperDirective {
|
||||
id = 'my-id';
|
||||
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: SuperDirective,
|
||||
selectors: [['', 'superDir', '']],
|
||||
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(),
|
||||
});
|
||||
}
|
||||
|
||||
class SubDirective extends SuperDirective {
|
||||
title = 'my-title';
|
||||
|
||||
static ngDirectiveDef = defineDirective({
|
||||
type: SubDirective,
|
||||
selectors: [['', 'subDir', '']],
|
||||
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]
|
||||
});
|
||||
}
|
||||
|
||||
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', () => {
|
||||
|
|
|
@ -1231,42 +1231,41 @@ import {NgModelCustomComp, NgModelCustomWrapper} from './value_accessor_integrat
|
|||
|
||||
describe('validation directives', () => {
|
||||
|
||||
fixmeIvy('RequiredValidator provided instead of CheckboxRequiredValidator') &&
|
||||
it('required validator should validate checkbox', fakeAsync(() => {
|
||||
const fixture = initTest(NgModelCheckboxRequiredValidator);
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
it('required validator should validate checkbox', fakeAsync(() => {
|
||||
const fixture = initTest(NgModelCheckboxRequiredValidator);
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
const control =
|
||||
fixture.debugElement.children[0].injector.get(NgForm).control.get('checkbox') !;
|
||||
const control =
|
||||
fixture.debugElement.children[0].injector.get(NgForm).control.get('checkbox') !;
|
||||
|
||||
const input = fixture.debugElement.query(By.css('input'));
|
||||
expect(input.nativeElement.checked).toBe(false);
|
||||
expect(control.hasError('required')).toBe(false);
|
||||
const input = fixture.debugElement.query(By.css('input'));
|
||||
expect(input.nativeElement.checked).toBe(false);
|
||||
expect(control.hasError('required')).toBe(false);
|
||||
|
||||
fixture.componentInstance.required = true;
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
fixture.componentInstance.required = true;
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
expect(input.nativeElement.checked).toBe(false);
|
||||
expect(control.hasError('required')).toBe(true);
|
||||
expect(input.nativeElement.checked).toBe(false);
|
||||
expect(control.hasError('required')).toBe(true);
|
||||
|
||||
input.nativeElement.checked = true;
|
||||
dispatchEvent(input.nativeElement, 'change');
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
input.nativeElement.checked = true;
|
||||
dispatchEvent(input.nativeElement, 'change');
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
expect(input.nativeElement.checked).toBe(true);
|
||||
expect(control.hasError('required')).toBe(false);
|
||||
expect(input.nativeElement.checked).toBe(true);
|
||||
expect(control.hasError('required')).toBe(false);
|
||||
|
||||
input.nativeElement.checked = false;
|
||||
dispatchEvent(input.nativeElement, 'change');
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
input.nativeElement.checked = false;
|
||||
dispatchEvent(input.nativeElement, 'change');
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
expect(input.nativeElement.checked).toBe(false);
|
||||
expect(control.hasError('required')).toBe(true);
|
||||
}));
|
||||
expect(input.nativeElement.checked).toBe(false);
|
||||
expect(control.hasError('required')).toBe(true);
|
||||
}));
|
||||
|
||||
it('should validate email', fakeAsync(() => {
|
||||
const fixture = initTest(NgModelEmailValidator);
|
||||
|
|
Loading…
Reference in New Issue