feat(ivy): support for the ngForOf directive, with tests (#21430)
Implement NgOnChangesFeature, ViewContainerRef, TemplateRef, and the renderEmbeddedTemplate instruction, and wire together the pieces required for the ngForOf directive to work. PR Close #21430
This commit is contained in:

committed by
Miško Hevery

parent
6472661ae8
commit
0ad02de47e
@ -6,13 +6,15 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {SimpleChange} from '../change_detection/change_detection_util';
|
||||
import {OnChanges, SimpleChanges} from '../metadata/lifecycle_hooks';
|
||||
import {RendererType2} from '../render/api';
|
||||
import {Type} from '../type';
|
||||
import {resolveRendererType2} from '../view/util';
|
||||
|
||||
import {diPublic} from './di';
|
||||
import {componentRefresh} from './instructions';
|
||||
import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs} from './interfaces/definition';
|
||||
import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs, TypedDirectiveDef} from './interfaces/definition';
|
||||
|
||||
|
||||
|
||||
@ -54,8 +56,57 @@ export function defineComponent<T>(componentDefinition: ComponentDefArgs<T>): Co
|
||||
return def;
|
||||
}
|
||||
|
||||
export function NgOnChangesFeature<T>(definition: DirectiveDef<T>) {
|
||||
// TODO: implement. See: https://app.asana.com/0/443577627818617/465170715764659
|
||||
|
||||
const PRIVATE_PREFIX = '__ngOnChanges_';
|
||||
|
||||
type OnChangesExpando = OnChanges & {
|
||||
__ngOnChanges_: SimpleChanges|null|undefined;
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
export function NgOnChangesFeature<T>(type: Type<T>): (definition: DirectiveDef<any>) => void {
|
||||
return function(definition: DirectiveDef<any>): void {
|
||||
const inputs = definition.inputs;
|
||||
const proto = 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 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);
|
||||
|
||||
// create a getter and setter for property
|
||||
Object.defineProperty(proto, minKey, {
|
||||
get: function(this: OnChangesExpando) {
|
||||
return (existingDesc && existingDesc.get) ? existingDesc.get.call(this) :
|
||||
this[privateMinKey];
|
||||
},
|
||||
set: function(this: OnChangesExpando, value: any) {
|
||||
let simpleChanges = this[PRIVATE_PREFIX];
|
||||
let isFirstChange = simpleChanges === undefined;
|
||||
if (simpleChanges == null) {
|
||||
simpleChanges = this[PRIVATE_PREFIX] = {};
|
||||
}
|
||||
simpleChanges[pubKey] = new SimpleChange(this[privateMinKey], value, isFirstChange);
|
||||
(existingDesc && existingDesc.set) ? existingDesc.set.call(this, value) :
|
||||
this[privateMinKey] = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
proto.ngDoCheck = (function(delegateDoCheck) {
|
||||
return function(this: OnChangesExpando) {
|
||||
let simpleChanges = this[PRIVATE_PREFIX];
|
||||
if (simpleChanges != null) {
|
||||
this.ngOnChanges(simpleChanges);
|
||||
this[PRIVATE_PREFIX] = null;
|
||||
}
|
||||
delegateDoCheck && delegateDoCheck.apply(this);
|
||||
};
|
||||
})(proto.ngDoCheck);
|
||||
};
|
||||
}
|
||||
|
||||
export function PublicFeature<T>(definition: DirectiveDef<T>) {
|
||||
|
Reference in New Issue
Block a user