feat(ivy): Add `outputs` support for `defineDirective` / `defineComponent` (#23168)
PR Close #23168
This commit is contained in:
parent
9a2479d423
commit
c059670792
|
@ -73,7 +73,10 @@ export function compileDirective(
|
||||||
field('attributes', createHostAttributesArray(directive, outputCtx));
|
field('attributes', createHostAttributesArray(directive, outputCtx));
|
||||||
|
|
||||||
// e.g 'inputs: {a: 'a'}`
|
// e.g 'inputs: {a: 'a'}`
|
||||||
field('inputs', createInputsObject(directive, outputCtx));
|
field('inputs', createMapObjectLiteral(directive.inputs, outputCtx));
|
||||||
|
|
||||||
|
// e.g 'outputs: {a: 'a'}`
|
||||||
|
field('outputs', createMapObjectLiteral(directive.outputs, outputCtx));
|
||||||
|
|
||||||
const className = identifierName(directive.type) !;
|
const className = identifierName(directive.type) !;
|
||||||
className || error(`Cannot resolver the name of ${directive.type}`);
|
className || error(`Cannot resolver the name of ${directive.type}`);
|
||||||
|
@ -193,7 +196,10 @@ export function compileComponent(
|
||||||
}
|
}
|
||||||
|
|
||||||
// e.g `inputs: {a: 'a'}`
|
// e.g `inputs: {a: 'a'}`
|
||||||
field('inputs', createInputsObject(component, outputCtx));
|
field('inputs', createMapObjectLiteral(component.inputs, outputCtx));
|
||||||
|
|
||||||
|
// e.g 'outputs: {a: 'a'}`
|
||||||
|
field('outputs', createMapObjectLiteral(component.outputs, outputCtx));
|
||||||
|
|
||||||
// e.g. `features: [NgOnChangesFeature(MyComponent)]`
|
// e.g. `features: [NgOnChangesFeature(MyComponent)]`
|
||||||
const features: o.Expression[] = [];
|
const features: o.Expression[] = [];
|
||||||
|
@ -1052,10 +1058,10 @@ function createHostBindingsFunction(
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createInputsObject(
|
function createMapObjectLiteral(
|
||||||
directive: CompileDirectiveMetadata, outputCtx: OutputContext): o.Expression|null {
|
keys: {[key: string]: string}, outputCtx: OutputContext): o.Expression|null {
|
||||||
if (Object.getOwnPropertyNames(directive.inputs).length > 0) {
|
if (Object.getOwnPropertyNames(keys).length > 0) {
|
||||||
return outputCtx.constantPool.getConstLiteral(mapToExpression(directive.inputs));
|
return mapToExpression(keys);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {MockDirectory, setup} from '../aot/test_util';
|
||||||
|
import {compile, expectEmit} from './mock_compile';
|
||||||
|
|
||||||
|
describe('compiler compliance: listen()', () => {
|
||||||
|
const angularFiles = setup({
|
||||||
|
compileAngular: true,
|
||||||
|
compileAnimations: false,
|
||||||
|
compileCommon: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create declare inputs/outputs', () => {
|
||||||
|
const files = {
|
||||||
|
app: {
|
||||||
|
'spec.ts': `
|
||||||
|
import {Component, Directive, NgModule, Input, Output} from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'my-component',
|
||||||
|
template: \`\`
|
||||||
|
})
|
||||||
|
export class MyComponent {
|
||||||
|
@Input() componentInput;
|
||||||
|
@Input('renamedComponentInput') originalComponentInput;
|
||||||
|
|
||||||
|
@Output() componentOutput;
|
||||||
|
@Output('renamedComponentOutput') originalComponentOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[my-directive]',
|
||||||
|
})
|
||||||
|
export class MyDirective {
|
||||||
|
@Input() directiveInput;
|
||||||
|
@Input('renamedDirectiveInput') originalDirectiveInput;
|
||||||
|
|
||||||
|
@Output() directiveOutput;
|
||||||
|
@Output('renamedDirectiveOutput') originalDirectiveOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({declarations: [MyComponent, MyDirective]})
|
||||||
|
export class MyModule {}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// The template should look like this (where IDENT is a wild card for an identifier):
|
||||||
|
const template = `
|
||||||
|
static ngComponentDef = i0.ɵdefineComponent({
|
||||||
|
…
|
||||||
|
inputs:{
|
||||||
|
componentInput: 'componentInput',
|
||||||
|
originalComponentInput: 'renamedComponentInput'
|
||||||
|
},
|
||||||
|
outputs: {
|
||||||
|
componentOutput: 'componentOutput',
|
||||||
|
originalComponentOutput: 'renamedComponentOutput'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
…
|
||||||
|
static ngDirectiveDef = i0.ɵdefineDirective({
|
||||||
|
…
|
||||||
|
inputs:{
|
||||||
|
directiveInput: 'directiveInput',
|
||||||
|
originalDirectiveInput: 'renamedDirectiveInput'
|
||||||
|
},
|
||||||
|
outputs: {
|
||||||
|
directiveOutput: 'directiveOutput',
|
||||||
|
originalDirectiveOutput: 'renamedDirectiveOutput'
|
||||||
|
}
|
||||||
|
});`;
|
||||||
|
|
||||||
|
|
||||||
|
const result = compile(files, angularFiles);
|
||||||
|
|
||||||
|
expectEmit(result.source, template, 'Incorrect template');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
Loading…
Reference in New Issue