feat(view): added support for exportAs, so any directive can be assigned to a variable
This commit is contained in:
parent
4eb8c9b2dd
commit
69b75b7fd8
@ -746,9 +746,35 @@ export class Directive extends Injectable {
|
|||||||
*/
|
*/
|
||||||
hostInjector: List<any>;
|
hostInjector: List<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the name that can be used in the template to assign this directive to a variable.
|
||||||
|
*
|
||||||
|
* ## Simple Example
|
||||||
|
*
|
||||||
|
* @Directive({
|
||||||
|
* selector: 'child-dir',
|
||||||
|
* exportAs: 'child'
|
||||||
|
* })
|
||||||
|
* class ChildDir {
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @Component({
|
||||||
|
* selector: 'main',
|
||||||
|
* })
|
||||||
|
* @View({
|
||||||
|
* template: `<child-dir #c="child"></child-dir>`,
|
||||||
|
* directives: [ChildDir]
|
||||||
|
* })
|
||||||
|
* class MainComponent {
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
exportAs: string;
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
selector, properties, events, hostListeners, hostProperties, hostAttributes,
|
selector, properties, events, hostListeners, hostProperties, hostAttributes,
|
||||||
hostActions, lifecycle, hostInjector, compileChildren = true,
|
hostActions, lifecycle, hostInjector, exportAs, compileChildren = true,
|
||||||
}: {
|
}: {
|
||||||
selector?: string,
|
selector?: string,
|
||||||
properties?: List<string>,
|
properties?: List<string>,
|
||||||
@ -759,6 +785,7 @@ export class Directive extends Injectable {
|
|||||||
hostActions?: StringMap<string, string>,
|
hostActions?: StringMap<string, string>,
|
||||||
lifecycle?: List<LifecycleEvent>,
|
lifecycle?: List<LifecycleEvent>,
|
||||||
hostInjector?: List<any>,
|
hostInjector?: List<any>,
|
||||||
|
exportAs?: string,
|
||||||
compileChildren?: boolean
|
compileChildren?: boolean
|
||||||
} = {}) {
|
} = {}) {
|
||||||
super();
|
super();
|
||||||
@ -769,6 +796,7 @@ export class Directive extends Injectable {
|
|||||||
this.hostProperties = hostProperties;
|
this.hostProperties = hostProperties;
|
||||||
this.hostAttributes = hostAttributes;
|
this.hostAttributes = hostAttributes;
|
||||||
this.hostActions = hostActions;
|
this.hostActions = hostActions;
|
||||||
|
this.exportAs = exportAs;
|
||||||
this.lifecycle = lifecycle;
|
this.lifecycle = lifecycle;
|
||||||
this.compileChildren = compileChildren;
|
this.compileChildren = compileChildren;
|
||||||
this.hostInjector = hostInjector;
|
this.hostInjector = hostInjector;
|
||||||
@ -973,7 +1001,7 @@ export class Component extends Directive {
|
|||||||
viewInjector: List<any>;
|
viewInjector: List<any>;
|
||||||
|
|
||||||
constructor({selector, properties, events, hostListeners, hostProperties, hostAttributes,
|
constructor({selector, properties, events, hostListeners, hostProperties, hostAttributes,
|
||||||
hostActions, appInjector, lifecycle, hostInjector, viewInjector,
|
hostActions, exportAs, appInjector, lifecycle, hostInjector, viewInjector,
|
||||||
changeDetection = DEFAULT, compileChildren = true}: {
|
changeDetection = DEFAULT, compileChildren = true}: {
|
||||||
selector?: string,
|
selector?: string,
|
||||||
properties?: List<string>,
|
properties?: List<string>,
|
||||||
@ -982,6 +1010,7 @@ export class Component extends Directive {
|
|||||||
hostProperties?: StringMap<string, string>,
|
hostProperties?: StringMap<string, string>,
|
||||||
hostAttributes?: StringMap<string, string>,
|
hostAttributes?: StringMap<string, string>,
|
||||||
hostActions?: StringMap<string, string>,
|
hostActions?: StringMap<string, string>,
|
||||||
|
exportAs?: string,
|
||||||
appInjector?: List<any>,
|
appInjector?: List<any>,
|
||||||
lifecycle?: List<LifecycleEvent>,
|
lifecycle?: List<LifecycleEvent>,
|
||||||
hostInjector?: List<any>,
|
hostInjector?: List<any>,
|
||||||
@ -997,6 +1026,7 @@ export class Component extends Directive {
|
|||||||
hostProperties: hostProperties,
|
hostProperties: hostProperties,
|
||||||
hostAttributes: hostAttributes,
|
hostAttributes: hostAttributes,
|
||||||
hostActions: hostActions,
|
hostActions: hostActions,
|
||||||
|
exportAs: exportAs,
|
||||||
hostInjector: hostInjector,
|
hostInjector: hostInjector,
|
||||||
lifecycle: lifecycle,
|
lifecycle: lifecycle,
|
||||||
compileChildren: compileChildren
|
compileChildren: compileChildren
|
||||||
|
@ -8,8 +8,10 @@ import * as viewModule from './view';
|
|||||||
export class ElementBinder {
|
export class ElementBinder {
|
||||||
nestedProtoView: viewModule.AppProtoView;
|
nestedProtoView: viewModule.AppProtoView;
|
||||||
hostListeners: StringMap<string, Map<number, AST>>;
|
hostListeners: StringMap<string, Map<number, AST>>;
|
||||||
|
|
||||||
constructor(public index: int, public parent: ElementBinder, public distanceToParent: int,
|
constructor(public index: int, public parent: ElementBinder, public distanceToParent: int,
|
||||||
public protoElementInjector: eiModule.ProtoElementInjector,
|
public protoElementInjector: eiModule.ProtoElementInjector,
|
||||||
|
public directiveVariableBindings: Map<string, number>,
|
||||||
public componentDirective: DirectiveBinding) {
|
public componentDirective: DirectiveBinding) {
|
||||||
if (isBlank(index)) {
|
if (isBlank(index)) {
|
||||||
throw new BaseException('null index not allowed.');
|
throw new BaseException('null index not allowed.');
|
||||||
|
@ -317,7 +317,9 @@ export class DirectiveBinding extends ResolvedBinding {
|
|||||||
callOnAllChangesDone: hasLifecycleHook(onAllChangesDone, rb.key.token, ann),
|
callOnAllChangesDone: hasLifecycleHook(onAllChangesDone, rb.key.token, ann),
|
||||||
|
|
||||||
changeDetection: ann instanceof
|
changeDetection: ann instanceof
|
||||||
Component ? ann.changeDetection : null
|
Component ? ann.changeDetection : null,
|
||||||
|
|
||||||
|
exportAs: ann.exportAs
|
||||||
});
|
});
|
||||||
return new DirectiveBinding(rb.key, rb.factory, deps, rb.providedAsPromise,
|
return new DirectiveBinding(rb.key, rb.factory, deps, rb.providedAsPromise,
|
||||||
resolvedAppInjectables, resolvedHostInjectables,
|
resolvedAppInjectables, resolvedHostInjectables,
|
||||||
@ -422,15 +424,6 @@ export class ProtoElementInjector {
|
|||||||
eventEmitterAccessors: List<List<EventEmitterAccessor>>;
|
eventEmitterAccessors: List<List<EventEmitterAccessor>>;
|
||||||
hostActionAccessors: List<List<HostActionAccessor>>;
|
hostActionAccessors: List<List<HostActionAccessor>>;
|
||||||
|
|
||||||
/** Whether the element is exported as $implicit. */
|
|
||||||
exportElement: boolean;
|
|
||||||
|
|
||||||
/** Whether the component instance is exported as $implicit. */
|
|
||||||
exportComponent: boolean;
|
|
||||||
|
|
||||||
/** The variable name that will be set to $implicit for the element. */
|
|
||||||
exportImplicitName: string;
|
|
||||||
|
|
||||||
_strategy: _ProtoElementInjectorStrategy;
|
_strategy: _ProtoElementInjectorStrategy;
|
||||||
|
|
||||||
static create(parent: ProtoElementInjector, index: number, bindings: List<ResolvedBinding>,
|
static create(parent: ProtoElementInjector, index: number, bindings: List<ResolvedBinding>,
|
||||||
@ -483,9 +476,6 @@ export class ProtoElementInjector {
|
|||||||
|
|
||||||
constructor(public parent: ProtoElementInjector, public index: int, bd: List<BindingData>,
|
constructor(public parent: ProtoElementInjector, public index: int, bd: List<BindingData>,
|
||||||
public distanceToParent: number, public _firstBindingIsComponent: boolean) {
|
public distanceToParent: number, public _firstBindingIsComponent: boolean) {
|
||||||
this.exportComponent = false;
|
|
||||||
this.exportElement = false;
|
|
||||||
|
|
||||||
var length = bd.length;
|
var length = bd.length;
|
||||||
this.eventEmitterAccessors = ListWrapper.createFixedSize(length);
|
this.eventEmitterAccessors = ListWrapper.createFixedSize(length);
|
||||||
this.hostActionAccessors = ListWrapper.createFixedSize(length);
|
this.hostActionAccessors = ListWrapper.createFixedSize(length);
|
||||||
@ -1164,15 +1154,6 @@ export class ElementInjector extends TreeNode<ElementInjector> {
|
|||||||
|
|
||||||
hasInstances(): boolean { return this._constructionCounter > 0; }
|
hasInstances(): boolean { return this._constructionCounter > 0; }
|
||||||
|
|
||||||
/** Gets whether this element is exporting a component instance as $implicit. */
|
|
||||||
isExportingComponent(): boolean { return this._proto.exportComponent; }
|
|
||||||
|
|
||||||
/** Gets whether this element is exporting its element as $implicit. */
|
|
||||||
isExportingElement(): boolean { return this._proto.exportElement; }
|
|
||||||
|
|
||||||
/** Get the name to which this element's $implicit is to be assigned. */
|
|
||||||
getExportImplicitName(): string { return this._proto.exportImplicitName; }
|
|
||||||
|
|
||||||
getLightDomAppInjector(): Injector { return this._lightDomAppInjector; }
|
getLightDomAppInjector(): Injector { return this._lightDomAppInjector; }
|
||||||
|
|
||||||
getShadowDomAppInjector(): Injector { return this._shadowDomAppInjector; }
|
getShadowDomAppInjector(): Injector { return this._shadowDomAppInjector; }
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {Injectable} from 'angular2/di';
|
import {Injectable} from 'angular2/di';
|
||||||
|
|
||||||
import {List, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
import {List, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -309,7 +309,7 @@ function _createElementBinders(protoView, elementBinders, allDirectiveBindings)
|
|||||||
componentDirectiveBinding, directiveBindings);
|
componentDirectiveBinding, directiveBindings);
|
||||||
|
|
||||||
_createElementBinder(protoView, i, renderElementBinder, protoElementInjector,
|
_createElementBinder(protoView, i, renderElementBinder, protoElementInjector,
|
||||||
componentDirectiveBinding);
|
componentDirectiveBinding, directiveBindings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,28 +343,20 @@ function _createProtoElementInjector(binderIndex, parentPeiWithDistance, renderE
|
|||||||
parentPeiWithDistance.protoElementInjector, binderIndex, directiveBindings,
|
parentPeiWithDistance.protoElementInjector, binderIndex, directiveBindings,
|
||||||
isPresent(componentDirectiveBinding), parentPeiWithDistance.distance);
|
isPresent(componentDirectiveBinding), parentPeiWithDistance.distance);
|
||||||
protoElementInjector.attributes = renderElementBinder.readAttributes;
|
protoElementInjector.attributes = renderElementBinder.readAttributes;
|
||||||
if (hasVariables) {
|
|
||||||
protoElementInjector.exportComponent = isPresent(componentDirectiveBinding);
|
|
||||||
protoElementInjector.exportElement = isBlank(componentDirectiveBinding);
|
|
||||||
|
|
||||||
// experiment
|
|
||||||
var exportImplicitName = MapWrapper.get(renderElementBinder.variableBindings, '\$implicit');
|
|
||||||
if (isPresent(exportImplicitName)) {
|
|
||||||
protoElementInjector.exportImplicitName = exportImplicitName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return protoElementInjector;
|
return protoElementInjector;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _createElementBinder(protoView, boundElementIndex, renderElementBinder,
|
function _createElementBinder(protoView, boundElementIndex, renderElementBinder,
|
||||||
protoElementInjector, componentDirectiveBinding): ElementBinder {
|
protoElementInjector, componentDirectiveBinding, directiveBindings): ElementBinder {
|
||||||
var parent = null;
|
var parent = null;
|
||||||
if (renderElementBinder.parentIndex !== -1) {
|
if (renderElementBinder.parentIndex !== -1) {
|
||||||
parent = protoView.elementBinders[renderElementBinder.parentIndex];
|
parent = protoView.elementBinders[renderElementBinder.parentIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var directiveVariableBindings = createDirectiveVariableBindings(renderElementBinder, directiveBindings);
|
||||||
var elBinder = protoView.bindElement(parent, renderElementBinder.distanceToParent,
|
var elBinder = protoView.bindElement(parent, renderElementBinder.distanceToParent,
|
||||||
protoElementInjector, componentDirectiveBinding);
|
protoElementInjector, directiveVariableBindings, componentDirectiveBinding);
|
||||||
protoView.bindEvent(renderElementBinder.eventBindings, boundElementIndex, -1);
|
protoView.bindEvent(renderElementBinder.eventBindings, boundElementIndex, -1);
|
||||||
// variables
|
// variables
|
||||||
// The view's locals needs to have a full set of variable names at construction time
|
// The view's locals needs to have a full set of variable names at construction time
|
||||||
@ -377,6 +369,49 @@ function _createElementBinder(protoView, boundElementIndex, renderElementBinder,
|
|||||||
return elBinder;
|
return elBinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createDirectiveVariableBindings(renderElementBinder:renderApi.ElementBinder,
|
||||||
|
directiveBindings:List<DirectiveBinding>): Map<String, number> {
|
||||||
|
var directiveVariableBindings = MapWrapper.create();
|
||||||
|
MapWrapper.forEach(renderElementBinder.variableBindings, (templateName, exportAs) => {
|
||||||
|
var dirIndex = _findDirectiveIndexByExportAs(renderElementBinder, directiveBindings, exportAs);
|
||||||
|
MapWrapper.set(directiveVariableBindings, templateName, dirIndex);
|
||||||
|
});
|
||||||
|
return directiveVariableBindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _findDirectiveIndexByExportAs(renderElementBinder, directiveBindings, exportAs) {
|
||||||
|
var matchedDirectiveIndex = null;
|
||||||
|
var matchedDirective;
|
||||||
|
|
||||||
|
for (var i = 0; i < directiveBindings.length; ++i) {
|
||||||
|
var directive = directiveBindings[i];
|
||||||
|
|
||||||
|
if (_directiveExportAs(directive) == exportAs) {
|
||||||
|
if (isPresent(matchedDirective)) {
|
||||||
|
throw new BaseException(`More than one directive have exportAs = '${exportAs}'. Directives: [${matchedDirective.displayName}, ${directive.displayName}]`);
|
||||||
|
}
|
||||||
|
|
||||||
|
matchedDirectiveIndex = i;
|
||||||
|
matchedDirective = directive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBlank(matchedDirective) && exportAs !== "$implicit") {
|
||||||
|
throw new BaseException(`Cannot find directive with exportAs = '${exportAs}'`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return matchedDirectiveIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _directiveExportAs(directive):string {
|
||||||
|
var directiveExportAs = directive.metadata.exportAs;
|
||||||
|
if (isBlank(directiveExportAs) && directive.metadata.type === renderApi.DirectiveMetadata.COMPONENT_TYPE) {
|
||||||
|
return "$implicit";
|
||||||
|
} else {
|
||||||
|
return directiveExportAs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function _bindDirectiveEvents(protoView, elementBinders: List<renderApi.ElementBinder>) {
|
function _bindDirectiveEvents(protoView, elementBinders: List<renderApi.ElementBinder>) {
|
||||||
for (var boundElementIndex = 0; boundElementIndex < elementBinders.length; ++boundElementIndex) {
|
for (var boundElementIndex = 0; boundElementIndex < elementBinders.length; ++boundElementIndex) {
|
||||||
var dirs = elementBinders[boundElementIndex].directives;
|
var dirs = elementBinders[boundElementIndex].directives;
|
||||||
|
@ -183,9 +183,12 @@ export class AppProtoView {
|
|||||||
|
|
||||||
bindElement(parent: ElementBinder, distanceToParent: int,
|
bindElement(parent: ElementBinder, distanceToParent: int,
|
||||||
protoElementInjector: ProtoElementInjector,
|
protoElementInjector: ProtoElementInjector,
|
||||||
|
directiveVariableBindings: Map<string, number>,
|
||||||
componentDirective: DirectiveBinding = null): ElementBinder {
|
componentDirective: DirectiveBinding = null): ElementBinder {
|
||||||
var elBinder = new ElementBinder(this.elementBinders.length, parent, distanceToParent,
|
var elBinder =
|
||||||
protoElementInjector, componentDirective);
|
new ElementBinder(this.elementBinders.length, parent, distanceToParent,
|
||||||
|
protoElementInjector, directiveVariableBindings, componentDirective);
|
||||||
|
|
||||||
ListWrapper.push(this.elementBinders, elBinder);
|
ListWrapper.push(this.elementBinders, elBinder);
|
||||||
return elBinder;
|
return elBinder;
|
||||||
}
|
}
|
||||||
|
@ -206,20 +206,22 @@ export class AppViewManagerUtils {
|
|||||||
|
|
||||||
var binders = view.proto.elementBinders;
|
var binders = view.proto.elementBinders;
|
||||||
for (var i = 0; i < binders.length; ++i) {
|
for (var i = 0; i < binders.length; ++i) {
|
||||||
|
var binder = binders[i];
|
||||||
var elementInjector = view.elementInjectors[i];
|
var elementInjector = view.elementInjectors[i];
|
||||||
|
|
||||||
if (isPresent(elementInjector)) {
|
if (isPresent(elementInjector)) {
|
||||||
elementInjector.hydrate(appInjector, hostElementInjector, view.preBuiltObjects[i]);
|
elementInjector.hydrate(appInjector, hostElementInjector, view.preBuiltObjects[i]);
|
||||||
this._setUpEventEmitters(view, elementInjector, i);
|
this._setUpEventEmitters(view, elementInjector, i);
|
||||||
this._setUpHostActions(view, elementInjector, i);
|
this._setUpHostActions(view, elementInjector, i);
|
||||||
|
|
||||||
// The exporting of $implicit is a special case. Since multiple elements will all export
|
if (isPresent(binder.directiveVariableBindings)) {
|
||||||
// the different values as $implicit, directly assign $implicit bindings to the variable
|
MapWrapper.forEach(binder.directiveVariableBindings, (directiveIndex, name) => {
|
||||||
// name.
|
if (isBlank(directiveIndex)) {
|
||||||
var exportImplicitName = elementInjector.getExportImplicitName();
|
view.locals.set(name, elementInjector.getElementRef().domElement);
|
||||||
if (elementInjector.isExportingComponent()) {
|
} else {
|
||||||
view.locals.set(exportImplicitName, elementInjector.getComponent());
|
view.locals.set(name, elementInjector.getDirectiveAtIndex(directiveIndex));
|
||||||
} else if (elementInjector.isExportingElement()) {
|
}
|
||||||
view.locals.set(exportImplicitName, elementInjector.getElementRef().domElement);
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ export class ElementBinder {
|
|||||||
directives: List<DirectiveBinder>;
|
directives: List<DirectiveBinder>;
|
||||||
nestedProtoView: ProtoViewDto;
|
nestedProtoView: ProtoViewDto;
|
||||||
propertyBindings: Map<string, ASTWithSource>;
|
propertyBindings: Map<string, ASTWithSource>;
|
||||||
variableBindings: Map<string, ASTWithSource>;
|
variableBindings: Map<string, string>;
|
||||||
// Note: this contains a preprocessed AST
|
// Note: this contains a preprocessed AST
|
||||||
// that replaced the values that should be extracted from the element
|
// that replaced the values that should be extracted from the element
|
||||||
// with a local name
|
// with a local name
|
||||||
@ -52,7 +52,7 @@ export class ElementBinder {
|
|||||||
directives?: List<DirectiveBinder>,
|
directives?: List<DirectiveBinder>,
|
||||||
nestedProtoView?: ProtoViewDto,
|
nestedProtoView?: ProtoViewDto,
|
||||||
propertyBindings?: Map<string, ASTWithSource>,
|
propertyBindings?: Map<string, ASTWithSource>,
|
||||||
variableBindings?: Map<string, ASTWithSource>,
|
variableBindings?: Map<string, string>,
|
||||||
eventBindings?: List<EventBinding>,
|
eventBindings?: List<EventBinding>,
|
||||||
textBindings?: List<ASTWithSource>,
|
textBindings?: List<ASTWithSource>,
|
||||||
readAttributes?: Map<string, string>
|
readAttributes?: Map<string, string>
|
||||||
@ -142,9 +142,10 @@ export class DirectiveMetadata {
|
|||||||
callOnInit: boolean;
|
callOnInit: boolean;
|
||||||
callOnAllChangesDone: boolean;
|
callOnAllChangesDone: boolean;
|
||||||
changeDetection: string;
|
changeDetection: string;
|
||||||
|
exportAs: string;
|
||||||
constructor({id, selector, compileChildren, events, hostListeners, hostProperties, hostAttributes,
|
constructor({id, selector, compileChildren, events, hostListeners, hostProperties, hostAttributes,
|
||||||
hostActions, properties, readAttributes, type, callOnDestroy, callOnChange,
|
hostActions, properties, readAttributes, type, callOnDestroy, callOnChange,
|
||||||
callOnCheck, callOnInit, callOnAllChangesDone, changeDetection}: {
|
callOnCheck, callOnInit, callOnAllChangesDone, changeDetection, exportAs}: {
|
||||||
id?: string,
|
id?: string,
|
||||||
selector?: string,
|
selector?: string,
|
||||||
compileChildren?: boolean,
|
compileChildren?: boolean,
|
||||||
@ -161,7 +162,8 @@ export class DirectiveMetadata {
|
|||||||
callOnCheck?: boolean,
|
callOnCheck?: boolean,
|
||||||
callOnInit?: boolean,
|
callOnInit?: boolean,
|
||||||
callOnAllChangesDone?: boolean,
|
callOnAllChangesDone?: boolean,
|
||||||
changeDetection?: string
|
changeDetection?: string,
|
||||||
|
exportAs?: string
|
||||||
}) {
|
}) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.selector = selector;
|
this.selector = selector;
|
||||||
@ -180,6 +182,7 @@ export class DirectiveMetadata {
|
|||||||
this.callOnInit = callOnInit;
|
this.callOnInit = callOnInit;
|
||||||
this.callOnAllChangesDone = callOnAllChangesDone;
|
this.callOnAllChangesDone = callOnAllChangesDone;
|
||||||
this.changeDetection = changeDetection;
|
this.changeDetection = changeDetection;
|
||||||
|
this.exportAs = exportAs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ export function directiveMetadataToMap(meta: DirectiveMetadata): Map<string, any
|
|||||||
['properties', _cloneIfPresent(meta.properties)],
|
['properties', _cloneIfPresent(meta.properties)],
|
||||||
['readAttributes', _cloneIfPresent(meta.readAttributes)],
|
['readAttributes', _cloneIfPresent(meta.readAttributes)],
|
||||||
['type', meta.type],
|
['type', meta.type],
|
||||||
|
['exportAs', meta.exportAs],
|
||||||
['callOnDestroy', meta.callOnDestroy],
|
['callOnDestroy', meta.callOnDestroy],
|
||||||
['callOnCheck', meta.callOnCheck],
|
['callOnCheck', meta.callOnCheck],
|
||||||
['callOnInit', meta.callOnInit],
|
['callOnInit', meta.callOnInit],
|
||||||
@ -44,6 +45,7 @@ export function directiveMetadataFromMap(map: Map<string, any>): DirectiveMetada
|
|||||||
properties:<List<string>>_cloneIfPresent(MapWrapper.get(map, 'properties')),
|
properties:<List<string>>_cloneIfPresent(MapWrapper.get(map, 'properties')),
|
||||||
readAttributes:<List<string>>_cloneIfPresent(MapWrapper.get(map, 'readAttributes')),
|
readAttributes:<List<string>>_cloneIfPresent(MapWrapper.get(map, 'readAttributes')),
|
||||||
type:<number>MapWrapper.get(map, 'type'),
|
type:<number>MapWrapper.get(map, 'type'),
|
||||||
|
exportAs:<string>MapWrapper.get(map, 'exportAs'),
|
||||||
callOnDestroy:<boolean>MapWrapper.get(map, 'callOnDestroy'),
|
callOnDestroy:<boolean>MapWrapper.get(map, 'callOnDestroy'),
|
||||||
callOnCheck:<boolean>MapWrapper.get(map, 'callOnCheck'),
|
callOnCheck:<boolean>MapWrapper.get(map, 'callOnCheck'),
|
||||||
callOnChange:<boolean>MapWrapper.get(map, 'callOnChange'),
|
callOnChange:<boolean>MapWrapper.get(map, 'callOnChange'),
|
||||||
|
@ -420,11 +420,11 @@ function createProtoView(elementBinders = null) {
|
|||||||
|
|
||||||
function createComponentElementBinder(directiveResolver, type) {
|
function createComponentElementBinder(directiveResolver, type) {
|
||||||
var binding = createDirectiveBinding(directiveResolver, type);
|
var binding = createDirectiveBinding(directiveResolver, type);
|
||||||
return new ElementBinder(0, null, 0, null, binding);
|
return new ElementBinder(0, null, 0, null, null, binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createViewportElementBinder(nestedProtoView) {
|
function createViewportElementBinder(nestedProtoView) {
|
||||||
var elBinder = new ElementBinder(0, null, 0, null, null);
|
var elBinder = new ElementBinder(0, null, 0, null, null, null);
|
||||||
elBinder.nestedProtoView = nestedProtoView;
|
elBinder.nestedProtoView = nestedProtoView;
|
||||||
return elBinder;
|
return elBinder;
|
||||||
}
|
}
|
||||||
|
@ -422,110 +422,127 @@ export function main() {
|
|||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should assign the component instance to a var-',
|
describe("variable bindings", () => {
|
||||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
it('should assign a component to a var-',
|
||||||
tb.overrideView(MyComp, new viewAnn.View({
|
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||||
template: '<p><child-cmp var-alice></child-cmp></p>',
|
tb.overrideView(MyComp, new viewAnn.View({
|
||||||
directives: [ChildComp]
|
template: '<p><child-cmp var-alice></child-cmp></p>',
|
||||||
|
directives: [ChildComp]
|
||||||
|
}));
|
||||||
|
|
||||||
|
tb.createView(MyComp, {context: ctx})
|
||||||
|
.then((view) => {
|
||||||
|
expect(view.rawView.locals).not.toBe(null);
|
||||||
|
expect(view.rawView.locals.get('alice')).toBeAnInstanceOf(ChildComp);
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
tb.createView(MyComp, {context: ctx})
|
it('should assign a directive to a var-',
|
||||||
.then((view) => {
|
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||||
expect(view.rawView.locals).not.toBe(null);
|
tb.overrideView(MyComp, new viewAnn.View({
|
||||||
expect(view.rawView.locals.get('alice')).toBeAnInstanceOf(ChildComp);
|
template: '<p><div [export-dir] #localdir="dir"></div></p>',
|
||||||
|
directives: [ExportDir]
|
||||||
|
}));
|
||||||
|
|
||||||
async.done();
|
tb.createView(MyComp, {context: ctx})
|
||||||
})
|
.then((view) => {
|
||||||
}));
|
expect(view.rawView.locals).not.toBe(null);
|
||||||
|
expect(view.rawView.locals.get('localdir')).toBeAnInstanceOf(ExportDir);
|
||||||
|
|
||||||
it('should make the assigned component accessible in property bindings',
|
async.done();
|
||||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
});
|
||||||
tb.overrideView(MyComp, new viewAnn.View({
|
|
||||||
template: '<p><child-cmp var-alice></child-cmp>{{alice.ctxProp}}</p>',
|
|
||||||
directives: [ChildComp]
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
tb.createView(MyComp, {context: ctx})
|
it('should make the assigned component accessible in property bindings',
|
||||||
.then((view) => {
|
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||||
view.detectChanges();
|
tb.overrideView(MyComp, new viewAnn.View({
|
||||||
|
template: '<p><child-cmp var-alice></child-cmp>{{alice.ctxProp}}</p>',
|
||||||
|
directives: [ChildComp]
|
||||||
|
}));
|
||||||
|
|
||||||
expect(view.rootNodes).toHaveText('hellohello'); // this first one is the
|
tb.createView(MyComp, {context: ctx})
|
||||||
// component, the second one is
|
.then((view) => {
|
||||||
// the text binding
|
view.detectChanges();
|
||||||
async.done();
|
|
||||||
})
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should assign two component instances each with a var-',
|
expect(view.rootNodes).toHaveText('hellohello'); // this first one is the
|
||||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
// component, the second one is
|
||||||
tb.overrideView(MyComp, new viewAnn.View({
|
// the text binding
|
||||||
template: '<p><child-cmp var-alice></child-cmp><child-cmp var-bob></p>',
|
async.done();
|
||||||
directives: [ChildComp]
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
tb.createView(MyComp, {context: ctx})
|
it('should assign two component instances each with a var-',
|
||||||
.then((view) => {
|
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||||
|
tb.overrideView(MyComp, new viewAnn.View({
|
||||||
|
template: '<p><child-cmp var-alice></child-cmp><child-cmp var-bob></p>',
|
||||||
|
directives: [ChildComp]
|
||||||
|
}));
|
||||||
|
|
||||||
expect(view.rawView.locals).not.toBe(null);
|
tb.createView(MyComp, {context: ctx})
|
||||||
expect(view.rawView.locals.get('alice')).toBeAnInstanceOf(ChildComp);
|
.then((view) => {
|
||||||
expect(view.rawView.locals.get('bob')).toBeAnInstanceOf(ChildComp);
|
|
||||||
expect(view.rawView.locals.get('alice')).not.toBe(view.rawView.locals.get('bob'));
|
|
||||||
|
|
||||||
async.done();
|
expect(view.rawView.locals).not.toBe(null);
|
||||||
})
|
expect(view.rawView.locals.get('alice')).toBeAnInstanceOf(ChildComp);
|
||||||
}));
|
expect(view.rawView.locals.get('bob')).toBeAnInstanceOf(ChildComp);
|
||||||
|
expect(view.rawView.locals.get('alice'))
|
||||||
|
.not.toBe(view.rawView.locals.get('bob'));
|
||||||
|
|
||||||
it('should assign the component instance to a var- with shorthand syntax',
|
async.done();
|
||||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
})
|
||||||
tb.overrideView(
|
}));
|
||||||
MyComp, new viewAnn.View(
|
|
||||||
{template: '<child-cmp #alice></child-cmp>', directives: [ChildComp]}));
|
|
||||||
|
|
||||||
tb.createView(MyComp, {context: ctx})
|
it('should assign the component instance to a var- with shorthand syntax',
|
||||||
.then((view) => {
|
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||||
|
tb.overrideView(
|
||||||
|
MyComp,
|
||||||
|
new viewAnn.View(
|
||||||
|
{template: '<child-cmp #alice></child-cmp>', directives: [ChildComp]}));
|
||||||
|
|
||||||
expect(view.rawView.locals).not.toBe(null);
|
tb.createView(MyComp, {context: ctx})
|
||||||
expect(view.rawView.locals.get('alice')).toBeAnInstanceOf(ChildComp);
|
.then((view) => {
|
||||||
|
|
||||||
async.done();
|
expect(view.rawView.locals).not.toBe(null);
|
||||||
})
|
expect(view.rawView.locals.get('alice')).toBeAnInstanceOf(ChildComp);
|
||||||
}));
|
|
||||||
|
|
||||||
it('should assign the element instance to a user-defined variable',
|
async.done();
|
||||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
})
|
||||||
tb.overrideView(
|
}));
|
||||||
MyComp, new viewAnn.View({template: '<p><div var-alice><i>Hello</i></div></p>'}));
|
|
||||||
|
|
||||||
tb.createView(MyComp, {context: ctx})
|
it('should assign the element instance to a user-defined variable',
|
||||||
.then((view) => {
|
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||||
expect(view.rawView.locals).not.toBe(null);
|
tb.overrideView(
|
||||||
|
MyComp, new viewAnn.View({template: '<p><div var-alice><i>Hello</i></div></p>'}));
|
||||||
|
|
||||||
var value = view.rawView.locals.get('alice');
|
tb.createView(MyComp, {context: ctx})
|
||||||
expect(value).not.toBe(null);
|
.then((view) => {
|
||||||
expect(value.tagName.toLowerCase()).toEqual('div');
|
expect(view.rawView.locals).not.toBe(null);
|
||||||
|
|
||||||
async.done();
|
var value = view.rawView.locals.get('alice');
|
||||||
})
|
expect(value).not.toBe(null);
|
||||||
}));
|
expect(value.tagName.toLowerCase()).toEqual('div');
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
|
||||||
it('should assign the element instance to a user-defined variable with camelCase using dash-case',
|
it('should change dash-case to camel-case',
|
||||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||||
tb.overrideView(
|
tb.overrideView(MyComp, new viewAnn.View({
|
||||||
MyComp,
|
template: '<p><child-cmp var-super-alice></child-cmp></p>',
|
||||||
new viewAnn.View({template: '<p><div var-super-alice><i>Hello</i></div></p>'}));
|
directives: [ChildComp]
|
||||||
|
}));
|
||||||
|
|
||||||
tb.createView(MyComp, {context: ctx})
|
tb.createView(MyComp, {context: ctx})
|
||||||
.then((view) => {
|
.then((view) => {
|
||||||
expect(view.rawView.locals).not.toBe(null);
|
expect(view.rawView.locals).not.toBe(null);
|
||||||
|
expect(view.rawView.locals.get('superAlice')).toBeAnInstanceOf(ChildComp);
|
||||||
|
|
||||||
var value = view.rawView.locals.get('superAlice');
|
async.done();
|
||||||
expect(value).not.toBe(null);
|
});
|
||||||
expect(value.tagName.toLowerCase()).toEqual('div');
|
}));
|
||||||
|
});
|
||||||
async.done();
|
|
||||||
})
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe("ON_PUSH components", () => {
|
describe("ON_PUSH components", () => {
|
||||||
it("should use ChangeDetectorRef to manually request a check",
|
it("should use ChangeDetectorRef to manually request a check",
|
||||||
@ -1696,3 +1713,7 @@ class SomeImperativeViewport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Directive({selector: '[export-dir]', exportAs: 'dir'})
|
||||||
|
class ExportDir {
|
||||||
|
}
|
@ -20,9 +20,11 @@ import {MapWrapper} from 'angular2/src/facade/collection';
|
|||||||
import {ChangeDetection, ChangeDetectorDefinition} from 'angular2/change_detection';
|
import {ChangeDetection, ChangeDetectorDefinition} from 'angular2/change_detection';
|
||||||
import {
|
import {
|
||||||
ProtoViewFactory,
|
ProtoViewFactory,
|
||||||
getChangeDetectorDefinitions
|
getChangeDetectorDefinitions,
|
||||||
|
createDirectiveVariableBindings
|
||||||
} from 'angular2/src/core/compiler/proto_view_factory';
|
} from 'angular2/src/core/compiler/proto_view_factory';
|
||||||
import {Component, Directive} from 'angular2/annotations';
|
import {Component, Directive} from 'angular2/annotations';
|
||||||
|
import {Key} from 'angular2/di';
|
||||||
import {DirectiveResolver} from 'angular2/src/core/compiler/directive_resolver';
|
import {DirectiveResolver} from 'angular2/src/core/compiler/directive_resolver';
|
||||||
import {DirectiveBinding} from 'angular2/src/core/compiler/element_injector';
|
import {DirectiveBinding} from 'angular2/src/core/compiler/element_injector';
|
||||||
import * as renderApi from 'angular2/src/render/api';
|
import * as renderApi from 'angular2/src/render/api';
|
||||||
@ -65,12 +67,85 @@ export function main() {
|
|||||||
expect(pvs.length).toBe(1);
|
expect(pvs.length).toBe(1);
|
||||||
expect(pvs[0].render).toBe(renderPv.render);
|
expect(pvs[0].render).toBe(renderPv.render);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("createDirectiveVariableBindings", () => {
|
||||||
|
it("should calculate directive variable bindings", () => {
|
||||||
|
var dvbs = createDirectiveVariableBindings(
|
||||||
|
new renderApi.ElementBinder(
|
||||||
|
{variableBindings: MapWrapper.createFromStringMap({"exportName": "templateName"})}),
|
||||||
|
[
|
||||||
|
directiveBinding(
|
||||||
|
{metadata: new renderApi.DirectiveMetadata({exportAs: 'exportName'})}),
|
||||||
|
directiveBinding(
|
||||||
|
{metadata: new renderApi.DirectiveMetadata({exportAs: 'otherName'})})
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(dvbs).toEqual(MapWrapper.createFromStringMap({"templateName": 0}));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should set exportAs to $implicit for component with exportAs = null", () => {
|
||||||
|
var dvbs = createDirectiveVariableBindings(
|
||||||
|
new renderApi.ElementBinder(
|
||||||
|
{variableBindings: MapWrapper.createFromStringMap({"$implicit": "templateName"})}),
|
||||||
|
[
|
||||||
|
directiveBinding({
|
||||||
|
metadata: new renderApi.DirectiveMetadata(
|
||||||
|
{exportAs: null, type: renderApi.DirectiveMetadata.COMPONENT_TYPE})
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(dvbs).toEqual(MapWrapper.createFromStringMap({"templateName": 0}));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw we no directive exported with this name", () => {
|
||||||
|
expect(() => {
|
||||||
|
createDirectiveVariableBindings(
|
||||||
|
new renderApi.ElementBinder({
|
||||||
|
variableBindings:
|
||||||
|
MapWrapper.createFromStringMap({"someInvalidName": "templateName"})
|
||||||
|
}),
|
||||||
|
[
|
||||||
|
directiveBinding(
|
||||||
|
{metadata: new renderApi.DirectiveMetadata({exportAs: 'exportName'})})
|
||||||
|
]);
|
||||||
|
}).toThrowError(new RegExp("Cannot find directive with exportAs = 'someInvalidName'"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw when binding to a name exported by two directives", () => {
|
||||||
|
expect(() => {
|
||||||
|
createDirectiveVariableBindings(
|
||||||
|
new renderApi.ElementBinder({
|
||||||
|
variableBindings: MapWrapper.createFromStringMap({"exportName": "templateName"})
|
||||||
|
}),
|
||||||
|
[
|
||||||
|
directiveBinding(
|
||||||
|
{metadata: new renderApi.DirectiveMetadata({exportAs: 'exportName'})}),
|
||||||
|
directiveBinding(
|
||||||
|
{metadata: new renderApi.DirectiveMetadata({exportAs: 'exportName'})})
|
||||||
|
]);
|
||||||
|
}).toThrowError(new RegExp("More than one directive have exportAs = 'exportName'"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not throw when not binding to a name exported by two directives", () => {
|
||||||
|
expect(() => {
|
||||||
|
createDirectiveVariableBindings(
|
||||||
|
new renderApi.ElementBinder({variableBindings: MapWrapper.create()}), [
|
||||||
|
directiveBinding(
|
||||||
|
{metadata: new renderApi.DirectiveMetadata({exportAs: 'exportName'})}),
|
||||||
|
directiveBinding(
|
||||||
|
{metadata: new renderApi.DirectiveMetadata({exportAs: 'exportName'})})
|
||||||
|
]);
|
||||||
|
}).not.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function directiveBinding({metadata}: {metadata?: any} = {}) {
|
||||||
|
return new DirectiveBinding(Key.get("dummy"), null, [], false, [], [], [], metadata);
|
||||||
|
}
|
||||||
|
|
||||||
function createRenderProtoView(elementBinders = null, type: number = null) {
|
function createRenderProtoView(elementBinders = null, type: number = null) {
|
||||||
if (isBlank(type)) {
|
if (isBlank(type)) {
|
||||||
type = renderApi.ProtoViewDto.COMPONENT_VIEW_TYPE;
|
type = renderApi.ProtoViewDto.COMPONENT_VIEW_TYPE;
|
||||||
|
@ -58,11 +58,11 @@ export function main() {
|
|||||||
return DirectiveBinding.createFromType(type, annotation);
|
return DirectiveBinding.createFromType(type, annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createEmptyElBinder() { return new ElementBinder(0, null, 0, null, null); }
|
function createEmptyElBinder() { return new ElementBinder(0, null, 0, null, null, null); }
|
||||||
|
|
||||||
function createComponentElBinder(nestedProtoView = null) {
|
function createComponentElBinder(nestedProtoView = null) {
|
||||||
var binding = createDirectiveBinding(SomeComponent);
|
var binding = createDirectiveBinding(SomeComponent);
|
||||||
var binder = new ElementBinder(0, null, 0, null, binding);
|
var binder = new ElementBinder(0, null, 0, null, null, binding);
|
||||||
binder.nestedProtoView = nestedProtoView;
|
binder.nestedProtoView = nestedProtoView;
|
||||||
return binder;
|
return binder;
|
||||||
}
|
}
|
||||||
|
@ -48,11 +48,11 @@ export function main() {
|
|||||||
return DirectiveBinding.createFromType(type, annotation);
|
return DirectiveBinding.createFromType(type, annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createEmptyElBinder() { return new ElementBinder(0, null, 0, null, null); }
|
function createEmptyElBinder() { return new ElementBinder(0, null, 0, null, null, null); }
|
||||||
|
|
||||||
function createComponentElBinder(nestedProtoView = null) {
|
function createComponentElBinder(nestedProtoView = null) {
|
||||||
var binding = createDirectiveBinding(SomeComponent);
|
var binding = createDirectiveBinding(SomeComponent);
|
||||||
var binder = new ElementBinder(0, null, 0, null, binding);
|
var binder = new ElementBinder(0, null, 0, null, null, binding);
|
||||||
binder.nestedProtoView = nestedProtoView;
|
binder.nestedProtoView = nestedProtoView;
|
||||||
return binder;
|
return binder;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ export function main() {
|
|||||||
readAttributes: ['read1', 'read2'],
|
readAttributes: ['read1', 'read2'],
|
||||||
selector: 'some-comp',
|
selector: 'some-comp',
|
||||||
type: DirectiveMetadata.COMPONENT_TYPE,
|
type: DirectiveMetadata.COMPONENT_TYPE,
|
||||||
|
exportAs: 'aaa',
|
||||||
callOnDestroy: true,
|
callOnDestroy: true,
|
||||||
callOnChange: true,
|
callOnChange: true,
|
||||||
callOnCheck: true,
|
callOnCheck: true,
|
||||||
@ -40,6 +41,7 @@ export function main() {
|
|||||||
expect(MapWrapper.get(map, 'callOnChange')).toEqual(true);
|
expect(MapWrapper.get(map, 'callOnChange')).toEqual(true);
|
||||||
expect(MapWrapper.get(map, 'callOnInit')).toEqual(true);
|
expect(MapWrapper.get(map, 'callOnInit')).toEqual(true);
|
||||||
expect(MapWrapper.get(map, 'callOnAllChangesDone')).toEqual(true);
|
expect(MapWrapper.get(map, 'callOnAllChangesDone')).toEqual(true);
|
||||||
|
expect(MapWrapper.get(map, 'exportAs')).toEqual('aaa');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('mapToDirectiveMetadata', () => {
|
it('mapToDirectiveMetadata', () => {
|
||||||
@ -53,6 +55,7 @@ export function main() {
|
|||||||
['readAttributes', ['readTest1', 'readTest2']],
|
['readAttributes', ['readTest1', 'readTest2']],
|
||||||
['selector', 'testSelector'],
|
['selector', 'testSelector'],
|
||||||
['type', DirectiveMetadata.DIRECTIVE_TYPE],
|
['type', DirectiveMetadata.DIRECTIVE_TYPE],
|
||||||
|
['exportAs', 'aaa'],
|
||||||
['callOnDestroy', true],
|
['callOnDestroy', true],
|
||||||
['callOnCheck', true],
|
['callOnCheck', true],
|
||||||
['callOnInit', true],
|
['callOnInit', true],
|
||||||
@ -71,6 +74,7 @@ export function main() {
|
|||||||
expect(meta.readAttributes).toEqual(['readTest1', 'readTest2']);
|
expect(meta.readAttributes).toEqual(['readTest1', 'readTest2']);
|
||||||
expect(meta.selector).toEqual('testSelector');
|
expect(meta.selector).toEqual('testSelector');
|
||||||
expect(meta.type).toEqual(DirectiveMetadata.DIRECTIVE_TYPE);
|
expect(meta.type).toEqual(DirectiveMetadata.DIRECTIVE_TYPE);
|
||||||
|
expect(meta.exportAs).toEqual('aaa');
|
||||||
expect(meta.callOnDestroy).toEqual(true);
|
expect(meta.callOnDestroy).toEqual(true);
|
||||||
expect(meta.callOnCheck).toEqual(true);
|
expect(meta.callOnCheck).toEqual(true);
|
||||||
expect(meta.callOnInit).toEqual(true);
|
expect(meta.callOnInit).toEqual(true);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user