
committed by
Miško Hevery

parent
19368085aa
commit
46efd4b938
@ -104,7 +104,7 @@ export class ComponentFactoryNgElementStrategy implements NgElementStrategy {
|
||||
* Returns the component property value. If the component has not yet been created, the value is
|
||||
* retrieved from the cached initialization values.
|
||||
*/
|
||||
getPropertyValue(property: string): any {
|
||||
getInputValue(property: string): any {
|
||||
if (!this.componentRef) {
|
||||
return this.initialInputValues.get(property);
|
||||
}
|
||||
@ -116,8 +116,8 @@ export class ComponentFactoryNgElementStrategy implements NgElementStrategy {
|
||||
* Sets the input value for the property. If the component has not yet been created, the value is
|
||||
* cached and set when the component is created.
|
||||
*/
|
||||
setPropertyValue(property: string, value: any): void {
|
||||
if (strictEquals(value, this.getPropertyValue(property))) {
|
||||
setInputValue(property: string, value: any): void {
|
||||
if (strictEquals(value, this.getInputValue(property))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -158,7 +158,7 @@ export class ComponentFactoryNgElementStrategy implements NgElementStrategy {
|
||||
this.componentFactory.inputs.forEach(({propName}) => {
|
||||
const initialValue = this.initialInputValues.get(propName);
|
||||
if (initialValue) {
|
||||
this.setPropertyValue(propName, initialValue);
|
||||
this.setInputValue(propName, initialValue);
|
||||
} else {
|
||||
// Keep track of inputs that were not initialized in case we need to know this for
|
||||
// calling ngOnChanges with SimpleChanges
|
||||
@ -185,8 +185,11 @@ export class ComponentFactoryNgElementStrategy implements NgElementStrategy {
|
||||
return;
|
||||
}
|
||||
|
||||
(this.componentRef !.instance as any as OnChanges).ngOnChanges(this.inputChanges);
|
||||
// Cache the changes and set inputChanges to null to capture any changes that might occur
|
||||
// during ngOnChanges.
|
||||
const inputChanges = this.inputChanges;
|
||||
this.inputChanges = null;
|
||||
(this.componentRef !.instance as any as OnChanges).ngOnChanges(inputChanges);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -199,8 +202,8 @@ export class ComponentFactoryNgElementStrategy implements NgElementStrategy {
|
||||
}
|
||||
|
||||
this.scheduledChangeDetectionFn = scheduler.scheduleBeforeRender(() => {
|
||||
this.detectChanges();
|
||||
this.scheduledChangeDetectionFn = null;
|
||||
this.detectChanges();
|
||||
});
|
||||
}
|
||||
|
||||
@ -209,7 +212,7 @@ export class ComponentFactoryNgElementStrategy implements NgElementStrategy {
|
||||
*/
|
||||
protected recordInputChange(property: string, currentValue: any): void {
|
||||
// Do not record the change if the component does not implement `OnChanges`.
|
||||
if (!this.componentRef || !this.implementsOnChanges) {
|
||||
if (this.componentRef && !this.implementsOnChanges) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -228,7 +231,7 @@ export class ComponentFactoryNgElementStrategy implements NgElementStrategy {
|
||||
const isFirstChange = this.uninitializedInputs.has(property);
|
||||
this.uninitializedInputs.delete(property);
|
||||
|
||||
const previousValue = isFirstChange ? undefined : this.getPropertyValue(property);
|
||||
const previousValue = isFirstChange ? undefined : this.getInputValue(property);
|
||||
this.inputChanges[property] = new SimpleChange(previousValue, currentValue, isFirstChange);
|
||||
}
|
||||
|
||||
|
@ -29,8 +29,8 @@ export interface NgElementStrategy {
|
||||
|
||||
connect(element: HTMLElement): void;
|
||||
disconnect(): void;
|
||||
getPropertyValue(propName: string): any;
|
||||
setPropertyValue(propName: string, value: string): void;
|
||||
getInputValue(propName: string): any;
|
||||
setInputValue(propName: string, value: string): void;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,6 +42,8 @@ export abstract class NgElement extends HTMLElement {
|
||||
/**
|
||||
* Additional type information that can be added to the NgElement class for properties added based
|
||||
* on the inputs and methods of the underlying component.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export type WithProperties<P> = {
|
||||
[property in keyof P]: P[property]
|
||||
@ -59,14 +61,14 @@ export interface NgElementConfig {
|
||||
injector: Injector;
|
||||
strategyFactory?: NgElementStrategyFactory;
|
||||
propertyInputs?: string[];
|
||||
attributeToPropertyInputs?: Map<string, string>;
|
||||
attributeToPropertyInputs?: {[key: string]: string};
|
||||
}
|
||||
|
||||
/** Gets a map of default set of attributes to observe and the properties they affect. */
|
||||
function getDefaultAttributeToPropertyInputs(inputs: {propName: string, templateName: string}[]) {
|
||||
const attributeToPropertyInputs = new Map<string, string>();
|
||||
const attributeToPropertyInputs: {[key: string]: string} = {};
|
||||
inputs.forEach(({propName, templateName}) => {
|
||||
attributeToPropertyInputs.set(camelToDashCase(templateName), propName);
|
||||
attributeToPropertyInputs[camelToDashCase(templateName)] = propName;
|
||||
});
|
||||
|
||||
return attributeToPropertyInputs;
|
||||
@ -100,7 +102,7 @@ export function createNgElementConstructor<P>(
|
||||
config.attributeToPropertyInputs || getDefaultAttributeToPropertyInputs(inputs);
|
||||
|
||||
class NgElementImpl extends NgElement {
|
||||
static readonly observedAttributes = Array.from(attributeToPropertyInputs.keys());
|
||||
static readonly observedAttributes = Object.keys(attributeToPropertyInputs);
|
||||
|
||||
constructor(strategyFactoryOverride?: NgElementStrategyFactory) {
|
||||
super();
|
||||
@ -113,16 +115,16 @@ export function createNgElementConstructor<P>(
|
||||
|
||||
attributeChangedCallback(
|
||||
attrName: string, oldValue: string|null, newValue: string, namespace?: string): void {
|
||||
const propName = attributeToPropertyInputs.get(attrName) !;
|
||||
this.ngElementStrategy.setPropertyValue(propName, newValue);
|
||||
const propName = attributeToPropertyInputs[attrName] !;
|
||||
this.ngElementStrategy.setInputValue(propName, newValue);
|
||||
}
|
||||
|
||||
connectedCallback(): void {
|
||||
// Take element attribute inputs and set them as inputs on the strategy
|
||||
attributeToPropertyInputs.forEach((propName, attrName) => {
|
||||
const value = this.getAttribute(attrName);
|
||||
if (value) {
|
||||
this.ngElementStrategy.setPropertyValue(propName, value);
|
||||
NgElementImpl.observedAttributes.forEach(attrName => {
|
||||
const propName = attributeToPropertyInputs[attrName] !;
|
||||
if (this.hasAttribute(attrName)) {
|
||||
this.ngElementStrategy.setInputValue(propName, this.getAttribute(attrName) !);
|
||||
}
|
||||
});
|
||||
|
||||
@ -150,8 +152,8 @@ export function createNgElementConstructor<P>(
|
||||
const propertyInputs = config.propertyInputs || inputs.map(({propName}) => propName);
|
||||
propertyInputs.forEach(property => {
|
||||
Object.defineProperty(NgElementImpl.prototype, property, {
|
||||
get: function() { return this.ngElementStrategy.getPropertyValue(property); },
|
||||
set: function(newValue: any) { this.ngElementStrategy.setPropertyValue(property, newValue); },
|
||||
get: function() { return this.ngElementStrategy.getInputValue(property); },
|
||||
set: function(newValue: any) { this.ngElementStrategy.setInputValue(property, newValue); },
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
});
|
||||
|
@ -6,12 +6,6 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module
|
||||
* @description
|
||||
* Entry point for all public APIs of the common package.
|
||||
*/
|
||||
|
||||
import {Version} from '@angular/core';
|
||||
/**
|
||||
* @experimental
|
||||
|
Reference in New Issue
Block a user