fix(ivy): ngOnChanges to receive SimpleChanges with non minified property names as keys (#22352)

PR Close #22352
This commit is contained in:
Marc Laval
2018-02-21 18:12:02 +01:00
committed by Victor Berchet
parent f791862e52
commit 7effb0016c
4 changed files with 475 additions and 28 deletions

View File

@ -44,6 +44,7 @@ export function defineComponent<T>(componentDefinition: ComponentDefArgs<T>): Co
h: componentDefinition.hostBindings || noop,
attributes: componentDefinition.attributes || null,
inputs: invertObject(componentDefinition.inputs),
inputsPropertyName: componentDefinition.inputsPropertyName || null,
outputs: invertObject(componentDefinition.outputs),
methods: invertObject(componentDefinition.methods),
rendererType: resolveRendererType2(componentDefinition.rendererType) || null,
@ -72,10 +73,12 @@ type OnChangesExpando = OnChanges & {
export function NgOnChangesFeature(definition: DirectiveDef<any>): void {
const inputs = definition.inputs;
const proto = definition.type.prototype;
const inputsPropertyName = definition.inputsPropertyName;
// Place where we will store SimpleChanges if there is a change
Object.defineProperty(proto, PRIVATE_PREFIX, {value: undefined, writable: true});
for (let pubKey in inputs) {
const minKey = inputs[pubKey];
const propertyName = inputsPropertyName && inputsPropertyName[minKey] || pubKey;
const privateMinKey = PRIVATE_PREFIX + minKey;
// Create a place where the actual value will be stored and make it non-enumerable
Object.defineProperty(proto, privateMinKey, {value: undefined, writable: true});
@ -94,7 +97,7 @@ export function NgOnChangesFeature(definition: DirectiveDef<any>): void {
if (simpleChanges == null) {
simpleChanges = this[PRIVATE_PREFIX] = {};
}
simpleChanges[pubKey] = new SimpleChange(this[privateMinKey], value, isFirstChange);
simpleChanges[propertyName] = new SimpleChange(this[privateMinKey], value, isFirstChange);
(existingDesc && existingDesc.set) ? existingDesc.set.call(this, value) :
this[privateMinKey] = value;
}

View File

@ -37,23 +37,29 @@ export interface DirectiveDef<T> {
diPublic: ((def: DirectiveDef<any>) => void)|null;
/**
* List of inputs which are part of the components public API.
*
* The key is minified property name whereas the value is the original unminified name.
* A dictionary mapping the inputs' minified property names to their public API names, which
* are their aliases if any, or their original unminified property names
* (as in `@Input('alias') propertyName: any;`).
*/
readonly inputs: {[P in keyof T]: P};
/**
* List of outputs which are part of the components public API.
* A dictionary mapping the inputs' minified property names to the original unminified property
* names.
*
* The key is minified property name whereas the value is the original unminified name.=
* An entry is added if and only if the alias is different from the property name.
*/
readonly inputsPropertyName: {[P in keyof T]: P};
/**
* A dictionary mapping the outputs' minified property names to their public API names, which
* are their aliases if any, or their original unminified property names
* (as in `@Output('alias') propertyName: any;`).
*/
readonly outputs: {[P in keyof T]: P};
/**
* List of methods which are part of the components public API.
*
* The key is minified property name whereas the value is the original unminified name.
* A dictionary mapping the methods' minified names to their original unminified ones.
*/
readonly methods: {[P in keyof T]: P};
@ -150,6 +156,7 @@ export interface DirectiveDefArgs<T> {
factory: () => T | [T];
attributes?: string[];
inputs?: {[P in keyof T]?: string};
inputsPropertyName?: {[P in keyof T]?: string};
outputs?: {[P in keyof T]?: string};
methods?: {[P in keyof T]?: string};
features?: DirectiveDefFeature[];