refactor(ivy): remove inputsPropertyName (#22716)

Closes #22591

PR Close #22716
This commit is contained in:
Kara Erickson 2018-03-12 11:18:50 -07:00
parent 34e355a3b0
commit bd9d4df735
7 changed files with 72 additions and 64 deletions

View File

@ -15,7 +15,7 @@ import {Type} from '../type';
import {resolveRendererType2} from '../view/util'; import {resolveRendererType2} from '../view/util';
import {diPublic} from './di'; import {diPublic} from './di';
import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs, PipeDef, PipeType} from './interfaces/definition'; import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs, DirectiveDefFeature, PipeDef} from './interfaces/definition';
@ -45,7 +45,6 @@ export function defineComponent<T>(componentDefinition: ComponentDefArgs<T>): Co
h: componentDefinition.hostBindings || noop, h: componentDefinition.hostBindings || noop,
attributes: componentDefinition.attributes || null, attributes: componentDefinition.attributes || null,
inputs: invertObject(componentDefinition.inputs), inputs: invertObject(componentDefinition.inputs),
inputsPropertyName: componentDefinition.inputsPropertyName || null,
outputs: invertObject(componentDefinition.outputs), outputs: invertObject(componentDefinition.outputs),
rendererType: resolveRendererType2(componentDefinition.rendererType) || null, rendererType: resolveRendererType2(componentDefinition.rendererType) || null,
exportAs: componentDefinition.exportAs, exportAs: componentDefinition.exportAs,
@ -72,48 +71,73 @@ type OnChangesExpando = OnChanges & {
[key: string]: any; [key: string]: any;
}; };
export function NgOnChangesFeature(definition: DirectiveDef<any>): void { /**
const inputs = definition.inputs; * Creates an NgOnChangesFeature function for a component's features list.
const proto = definition.type.prototype; *
const inputsPropertyName = definition.inputsPropertyName; * It accepts an optional map of minified input property names to original property names,
// Place where we will store SimpleChanges if there is a change * if any input properties have a public alias.
Object.defineProperty(proto, PRIVATE_PREFIX, {value: undefined, writable: true}); *
for (let pubKey in inputs) { * The NgOnChangesFeature function that is returned decorates a component with support for
const minKey = inputs[pubKey]; * the ngOnChanges lifecycle hook, so it should be included in any component that implements
const propertyName = inputsPropertyName && inputsPropertyName[minKey] || pubKey; * that hook.
const privateMinKey = PRIVATE_PREFIX + minKey; *
// Create a place where the actual value will be stored and make it non-enumerable * Example usage:
Object.defineProperty(proto, privateMinKey, {value: undefined, writable: true}); *
* ```
* static ngComponentDef = defineComponent({
* ...
* inputs: {name: 'publicName'},
* features: [NgOnChangesFeature({name: 'name'})]
* });
* ```
*
* @param inputPropertyNames Map of input property names, if they are aliased
* @returns DirectiveDefFeature
*/
export function NgOnChangesFeature(inputPropertyNames?: {[key: string]: string}):
DirectiveDefFeature {
return function(definition: DirectiveDef<any>): void {
const inputs = definition.inputs;
const proto = definition.type.prototype;
// 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 = inputPropertyNames && inputPropertyNames[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});
const existingDesc = Object.getOwnPropertyDescriptor(proto, minKey); const existingDesc = Object.getOwnPropertyDescriptor(proto, minKey);
// create a getter and setter for property // create a getter and setter for property
Object.defineProperty(proto, minKey, { Object.defineProperty(proto, minKey, {
get: function(this: OnChangesExpando) { get: function(this: OnChangesExpando) {
return (existingDesc && existingDesc.get) ? existingDesc.get.call(this) : return (existingDesc && existingDesc.get) ? existingDesc.get.call(this) :
this[privateMinKey]; this[privateMinKey];
}, },
set: function(this: OnChangesExpando, value: any) { set: function(this: OnChangesExpando, value: any) {
let simpleChanges = this[PRIVATE_PREFIX]; let simpleChanges = this[PRIVATE_PREFIX];
let isFirstChange = simpleChanges === undefined; let isFirstChange = simpleChanges === undefined;
if (simpleChanges == null) { if (simpleChanges == null) {
simpleChanges = this[PRIVATE_PREFIX] = {}; simpleChanges = this[PRIVATE_PREFIX] = {};
}
simpleChanges[propertyName] = new SimpleChange(this[privateMinKey], value, isFirstChange);
(existingDesc && existingDesc.set) ? existingDesc.set.call(this, value) :
this[privateMinKey] = value;
} }
simpleChanges[propertyName] = new SimpleChange(this[privateMinKey], value, isFirstChange); });
(existingDesc && existingDesc.set) ? existingDesc.set.call(this, value) : }
this[privateMinKey] = value;
}
});
}
// If an onInit hook is defined, it will need to wrap the ngOnChanges call // If an onInit hook is defined, it will need to wrap the ngOnChanges call
// so the call order is changes-init-check in creation mode. In subsequent // so the call order is changes-init-check in creation mode. In subsequent
// change detection runs, only the check wrapper will be called. // change detection runs, only the check wrapper will be called.
if (definition.onInit != null) { if (definition.onInit != null) {
definition.onInit = onChangesWrapper(definition.onInit); definition.onInit = onChangesWrapper(definition.onInit);
} }
definition.doCheck = onChangesWrapper(definition.doCheck); definition.doCheck = onChangesWrapper(definition.doCheck);
};
function onChangesWrapper(delegateHook: (() => void) | null) { function onChangesWrapper(delegateHook: (() => void) | null) {
return function(this: OnChangesExpando) { return function(this: OnChangesExpando) {

View File

@ -68,14 +68,6 @@ export interface DirectiveDef<T> {
*/ */
readonly inputs: {[P in keyof T]: P}; readonly inputs: {[P in keyof T]: P};
/**
* A dictionary mapping the inputs' minified property names to the original unminified property
* names.
*
* 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 * 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 * are their aliases if any, or their original unminified property names
@ -240,11 +232,6 @@ export interface DirectiveDefArgs<T> {
*/ */
inputs?: {[P in keyof T]?: string}; inputs?: {[P in keyof T]?: string};
/**
* TODO: Remove per https://github.com/angular/angular/issues/22591
*/
inputsPropertyName?: {[P in keyof T]?: string};
/** /**
* A map of output names. * A map of output names.
* *

View File

@ -19,7 +19,7 @@ NgForOf.ngDirectiveDef = defineDirective({
factory: () => new NgForOfDef( factory: () => new NgForOfDef(
injectViewContainerRef(), injectTemplateRef(), injectViewContainerRef(), injectTemplateRef(),
directiveInject(IterableDiffers, InjectFlags.Default, defaultIterableDiffers)), directiveInject(IterableDiffers, InjectFlags.Default, defaultIterableDiffers)),
features: [NgOnChangesFeature], features: [NgOnChangesFeature()],
inputs: { inputs: {
ngForOf: 'ngForOf', ngForOf: 'ngForOf',
ngForTrackBy: 'ngForTrackBy', ngForTrackBy: 'ngForTrackBy',

View File

@ -45,8 +45,7 @@ describe('lifecycle hooks', () => {
factory: function LifecycleComp_Factory() { return new LifecycleComp(); }, factory: function LifecycleComp_Factory() { return new LifecycleComp(); },
template: function LifecycleComp_Template(ctx: $LifecycleComp$, cm: $boolean$) {}, template: function LifecycleComp_Template(ctx: $LifecycleComp$, cm: $boolean$) {},
inputs: {nameMin: 'name'}, inputs: {nameMin: 'name'},
inputsPropertyName: {nameMin: 'nameMin'}, features: [$r3$.ɵNgOnChangesFeature({nameMin: 'nameMin'})]
features: [$r3$.ɵNgOnChangesFeature]
}); });
// /NORMATIVE // /NORMATIVE
} }

View File

@ -30,7 +30,7 @@ describe('define', () => {
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
type: MyDirective, type: MyDirective,
factory: () => new MyDirective(), factory: () => new MyDirective(),
features: [NgOnChangesFeature], features: [NgOnChangesFeature()],
inputs: {valA: 'valA', valB: 'valB'} inputs: {valA: 'valA', valB: 'valB'}
}); });
} }

View File

@ -420,7 +420,7 @@ describe('di', () => {
type: IfDirective, type: IfDirective,
factory: () => new IfDirective(injectTemplateRef(), injectViewContainerRef()), factory: () => new IfDirective(injectTemplateRef(), injectViewContainerRef()),
inputs: {myIf: 'myIf'}, inputs: {myIf: 'myIf'},
features: [PublicFeature, NgOnChangesFeature] features: [PublicFeature, NgOnChangesFeature()]
}); });
} }

View File

@ -1987,9 +1987,8 @@ describe('lifecycles', () => {
type: Component, type: Component,
tag: name, tag: name,
factory: () => new Component(), factory: () => new Component(),
features: [NgOnChangesFeature], features: [NgOnChangesFeature({b: 'val2'})],
inputs: {a: 'val1', b: 'publicName'}, inputs: {a: 'val1', b: 'publicName'}, template
inputsPropertyName: {b: 'val2'}, template
}); });
}; };
} }
@ -2007,9 +2006,8 @@ describe('lifecycles', () => {
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
type: Directive, type: Directive,
factory: () => new Directive(), factory: () => new Directive(),
features: [NgOnChangesFeature], features: [NgOnChangesFeature({b: 'val2'})],
inputs: {a: 'val1', b: 'publicName'}, inputs: {a: 'val1', b: 'publicName'}
inputsPropertyName: {b: 'val2'}
}); });
} }
@ -2397,7 +2395,7 @@ describe('lifecycles', () => {
tag: name, tag: name,
factory: () => new Component(), factory: () => new Component(),
inputs: {val: 'val'}, template, inputs: {val: 'val'}, template,
features: [NgOnChangesFeature] features: [NgOnChangesFeature()]
}); });
}; };
} }