mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(core): host directives incorrectly validating aliased bindings (#50364)
Fixes that the host directives feature was incorrectly throwing the conflicting alias error when an aliased binding was being exposed under the same alias. Fixes #48951. PR Close #50364
This commit is contained in:
committed by
Jessica Janiuk
parent
b89fae173e
commit
199ff4fe7f
@@ -944,6 +944,59 @@ runInEachFileSystem(() => {
|
||||
|
||||
expect(messages).toEqual([]);
|
||||
});
|
||||
|
||||
it('should not produce a diagnostic when exposing an aliased binding', () => {
|
||||
env.write('test.ts', `
|
||||
import {Directive, EventEmitter} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
outputs: ['opened: triggerOpened'],
|
||||
selector: '[trigger]',
|
||||
standalone: true,
|
||||
})
|
||||
export class Trigger {
|
||||
opened = new EventEmitter();
|
||||
}
|
||||
|
||||
@Directive({
|
||||
standalone: true,
|
||||
selector: '[host]',
|
||||
hostDirectives: [{directive: Trigger, outputs: ['triggerOpened']}]
|
||||
})
|
||||
export class Host {}
|
||||
`);
|
||||
|
||||
const diags = env.driveDiagnostics();
|
||||
expect(diags.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should not produce a diagnostic when exposing an inherited aliased binding', () => {
|
||||
env.write('test.ts', `
|
||||
import {Directive, EventEmitter} from '@angular/core';
|
||||
|
||||
@Directive({standalone: true})
|
||||
export abstract class Base {
|
||||
opened = new EventEmitter();
|
||||
}
|
||||
|
||||
@Directive({
|
||||
outputs: ['opened: triggerOpened'],
|
||||
selector: '[trigger]',
|
||||
standalone: true,
|
||||
})
|
||||
export class Trigger extends Base {}
|
||||
|
||||
@Directive({
|
||||
standalone: true,
|
||||
selector: '[host]',
|
||||
hostDirectives: [{directive: Trigger, outputs: ['triggerOpened: hostOpened']}]
|
||||
})
|
||||
export class Host {}
|
||||
`);
|
||||
|
||||
const diags = env.driveDiagnostics();
|
||||
expect(diags.length).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -204,7 +204,7 @@ function validateMappings(
|
||||
|
||||
const remappedPublicName = hostDirectiveBindings[publicName];
|
||||
|
||||
if (bindings.hasOwnProperty(remappedPublicName) &&
|
||||
if (bindings.hasOwnProperty(remappedPublicName) && remappedPublicName !== publicName &&
|
||||
bindings[remappedPublicName] !== publicName) {
|
||||
throw new RuntimeError(
|
||||
RuntimeErrorCode.HOST_DIRECTIVE_CONFLICTING_ALIAS,
|
||||
|
||||
@@ -3219,5 +3219,65 @@ describe('host directives', () => {
|
||||
fixture.detectChanges();
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not throw when exposing an aliased binding', () => {
|
||||
@Directive({
|
||||
outputs: ['opened: triggerOpened'],
|
||||
selector: '[trigger]',
|
||||
standalone: true,
|
||||
})
|
||||
class Trigger {
|
||||
opened = new EventEmitter();
|
||||
}
|
||||
|
||||
@Directive({
|
||||
standalone: true,
|
||||
selector: '[host]',
|
||||
hostDirectives: [{directive: Trigger, outputs: ['triggerOpened']}]
|
||||
})
|
||||
class Host {
|
||||
}
|
||||
|
||||
@Component({template: '<div host></div>', standalone: true, imports: [Host]})
|
||||
class App {
|
||||
}
|
||||
|
||||
expect(() => {
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not throw when exposing an inherited aliased binding', () => {
|
||||
@Directive({standalone: true})
|
||||
abstract class Base {
|
||||
opened = new EventEmitter();
|
||||
}
|
||||
|
||||
@Directive({
|
||||
outputs: ['opened: triggerOpened'],
|
||||
selector: '[trigger]',
|
||||
standalone: true,
|
||||
})
|
||||
class Trigger extends Base {
|
||||
}
|
||||
|
||||
@Directive({
|
||||
standalone: true,
|
||||
selector: '[host]',
|
||||
hostDirectives: [{directive: Trigger, outputs: ['triggerOpened: hostOpened']}]
|
||||
})
|
||||
class Host {
|
||||
}
|
||||
|
||||
@Component({template: '<div host></div>', standalone: true, imports: [Host]})
|
||||
class App {
|
||||
}
|
||||
|
||||
expect(() => {
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user