feat(vars): assignment of component or element instance to vars.
This commit is contained in:
parent
ab733bd80e
commit
6dbfe0dc2e
|
@ -211,10 +211,22 @@ export class ProtoElementInjector {
|
||||||
index:int;
|
index:int;
|
||||||
view:View;
|
view:View;
|
||||||
distanceToParent:number;
|
distanceToParent:number;
|
||||||
|
|
||||||
|
/** 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;
|
||||||
|
|
||||||
constructor(parent:ProtoElementInjector, index:int, bindings:List, firstBindingIsComponent:boolean = false, distanceToParent:number = 0) {
|
constructor(parent:ProtoElementInjector, index:int, bindings:List, firstBindingIsComponent:boolean = false, distanceToParent:number = 0) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.distanceToParent = distanceToParent;
|
this.distanceToParent = distanceToParent;
|
||||||
|
this.exportComponent = false;
|
||||||
|
this.exportElement = false;
|
||||||
|
|
||||||
this._binding0IsComponent = firstBindingIsComponent;
|
this._binding0IsComponent = firstBindingIsComponent;
|
||||||
this._binding0 = null; this._keyId0 = null;
|
this._binding0 = null; this._keyId0 = null;
|
||||||
|
@ -405,6 +417,11 @@ export class ElementInjector extends TreeNode {
|
||||||
return this._preBuiltObjects.element.domElement === el;
|
return this._preBuiltObjects.element.domElement === el;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets the NgElement associated with this ElementInjector */
|
||||||
|
getNgElement() {
|
||||||
|
return this._preBuiltObjects.element;
|
||||||
|
}
|
||||||
|
|
||||||
getComponent() {
|
getComponent() {
|
||||||
if (this._proto._binding0IsComponent) {
|
if (this._proto._binding0IsComponent) {
|
||||||
return this._obj0;
|
return this._obj0;
|
||||||
|
@ -603,6 +620,21 @@ export class ElementInjector extends TreeNode {
|
||||||
hasEventEmitter(eventName: string) {
|
hasEventEmitter(eventName: string) {
|
||||||
return this._proto.hasEventEmitter(eventName);
|
return this._proto.hasEventEmitter(eventName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets whether this element is exporting a component instance as $implicit. */
|
||||||
|
isExportingComponent() {
|
||||||
|
return this._proto.exportComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets whether this element is exporting its element as $implicit. */
|
||||||
|
isExportingElement() {
|
||||||
|
return this._proto.exportElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get the name to which this element's $implicit is to be assigned. */
|
||||||
|
getExportImplicitName() {
|
||||||
|
return this._proto.exportImplicitName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OutOfBoundsAccess extends Error {
|
class OutOfBoundsAccess extends Error {
|
||||||
|
|
|
@ -106,11 +106,17 @@ export class CompileElement {
|
||||||
MapWrapper.set(this.propertyBindings, property, expression);
|
MapWrapper.set(this.propertyBindings, property, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
addVariableBinding(directiveName:string, templateName:string) {
|
addVariableBinding(variableName:string, variableValue:string) {
|
||||||
if (isBlank(this.variableBindings)) {
|
if (isBlank(this.variableBindings)) {
|
||||||
this.variableBindings = MapWrapper.create();
|
this.variableBindings = MapWrapper.create();
|
||||||
}
|
}
|
||||||
MapWrapper.set(this.variableBindings, templateName, directiveName);
|
|
||||||
|
// Store the variable map from value to variable, reflecting how it will be used later by
|
||||||
|
// View. When a local is set to the view, a lookup for the variable name will take place keyed
|
||||||
|
// by the "value", or exported identifier. For example, ng-repeat sets a view local of "index".
|
||||||
|
// When this occurs, a lookup keyed by "index" must occur to find if there is a var referencing
|
||||||
|
// it.
|
||||||
|
MapWrapper.set(this.variableBindings, variableValue, variableName);
|
||||||
}
|
}
|
||||||
|
|
||||||
addEventBinding(eventName:string, expression:AST) {
|
addEventBinding(eventName:string, expression:AST) {
|
||||||
|
|
|
@ -9,7 +9,16 @@ import {CompileElement} from './compile_element';
|
||||||
import {CompileControl} from './compile_control';
|
import {CompileControl} from './compile_control';
|
||||||
|
|
||||||
// TODO(tbosch): Cannot make this const/final right now because of the transpiler...
|
// TODO(tbosch): Cannot make this const/final right now because of the transpiler...
|
||||||
var BIND_NAME_REGEXP = RegExpWrapper.create('^(?:(?:(bind)|(var)|(on))-(.+))|\\[([^\\]]+)\\]|\\(([^\\)]+)\\)');
|
// Group 1 = "bind"
|
||||||
|
// Group 2 = "var"
|
||||||
|
// Group 3 = "on"
|
||||||
|
// Group 4 = the identifier after "bind", "var", or "on"
|
||||||
|
// Group 5 = idenitifer inside square braces
|
||||||
|
// Group 6 = identifier inside parenthesis
|
||||||
|
// Group 7 = "#"
|
||||||
|
// Group 8 = identifier after "#"
|
||||||
|
var BIND_NAME_REGEXP = RegExpWrapper.create(
|
||||||
|
'^(?:(?:(bind)|(var)|(on))-(.+))|\\[([^\\]]+)\\]|\\(([^\\)]+)\\)|(#)(.+)');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the property bindings on a single element.
|
* Parses the property bindings on a single element.
|
||||||
|
@ -35,14 +44,12 @@ export class PropertyBindingParser extends CompileStep {
|
||||||
if (isPresent(bindParts[1])) {
|
if (isPresent(bindParts[1])) {
|
||||||
// match: bind-prop
|
// match: bind-prop
|
||||||
current.addPropertyBinding(bindParts[4], this._parseBinding(attrValue));
|
current.addPropertyBinding(bindParts[4], this._parseBinding(attrValue));
|
||||||
} else if (isPresent(bindParts[2])) {
|
} else if (isPresent(bindParts[2]) || isPresent(bindParts[7])) {
|
||||||
// match: let-prop
|
// match: var-name / var-name="iden" / #name / #name="iden"
|
||||||
// Note: We assume that the ViewSplitter already did its work, i.e. template directive should
|
var identifier = (isPresent(bindParts[4]) && bindParts[4] !== '') ?
|
||||||
// only be present on <template> elements any more!
|
bindParts[4] : bindParts[8];
|
||||||
if (!(current.element instanceof TemplateElement)) {
|
var value = attrValue == '' ? '\$implicit' : attrValue;
|
||||||
throw new BaseException('var-* is only allowed on <template> elements!');
|
current.addVariableBinding(identifier, value);
|
||||||
}
|
|
||||||
current.addVariableBinding(bindParts[4], attrValue);
|
|
||||||
} else if (isPresent(bindParts[3])) {
|
} else if (isPresent(bindParts[3])) {
|
||||||
// match: on-prop
|
// match: on-prop
|
||||||
current.addEventBinding(bindParts[4], this._parseAction(attrValue));
|
current.addEventBinding(bindParts[4], this._parseAction(attrValue));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
import {Key} from 'angular2/di';
|
import {Key} from 'angular2/di';
|
||||||
import {ProtoElementInjector, ComponentKeyMetaData, DirectiveBinding} from '../element_injector';
|
import {ProtoElementInjector, ComponentKeyMetaData, DirectiveBinding} from '../element_injector';
|
||||||
|
@ -39,7 +39,10 @@ export class ProtoElementInjectorBuilder extends CompileStep {
|
||||||
// but after the directives as we rely on that order
|
// but after the directives as we rely on that order
|
||||||
// in the element_binder_builder.
|
// in the element_binder_builder.
|
||||||
|
|
||||||
if (injectorBindings.length > 0) {
|
// Create a protoElementInjector for any element that either has bindings *or* has one
|
||||||
|
// or more var- defined. Elements with a var- defined need a their own element injector
|
||||||
|
// so that, when hydrating, $implicit can be set to the element.
|
||||||
|
if (injectorBindings.length > 0 || isPresent(current.variableBindings)) {
|
||||||
var protoView = current.inheritedProtoView;
|
var protoView = current.inheritedProtoView;
|
||||||
var hasComponent = isPresent(current.componentDirective);
|
var hasComponent = isPresent(current.componentDirective);
|
||||||
|
|
||||||
|
@ -49,6 +52,18 @@ export class ProtoElementInjectorBuilder extends CompileStep {
|
||||||
);
|
);
|
||||||
current.distanceToParentInjector = 0;
|
current.distanceToParentInjector = 0;
|
||||||
|
|
||||||
|
// Template directives are treated differently than other element with var- definitions.
|
||||||
|
if (isPresent(current.variableBindings) && !isPresent(current.templateDirective)) {
|
||||||
|
current.inheritedProtoElementInjector.exportComponent = hasComponent;
|
||||||
|
current.inheritedProtoElementInjector.exportElement = !hasComponent;
|
||||||
|
|
||||||
|
// experiment
|
||||||
|
var exportImplicitName = MapWrapper.get(current.variableBindings, '\$implicit');
|
||||||
|
if (isPresent(exportImplicitName)) {
|
||||||
|
current.inheritedProtoElementInjector.exportImplicitName = exportImplicitName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
current.inheritedProtoElementInjector = parentProtoElementInjector;
|
current.inheritedProtoElementInjector = parentProtoElementInjector;
|
||||||
current.distanceToParentInjector = distanceToParentInjector;
|
current.distanceToParentInjector = distanceToParentInjector;
|
||||||
|
|
|
@ -40,6 +40,10 @@ export class ProtoViewBuilder extends CompileStep {
|
||||||
throw new BaseException('Only one nested view per element is allowed');
|
throw new BaseException('Only one nested view per element is allowed');
|
||||||
}
|
}
|
||||||
parent.inheritedElementBinder.nestedProtoView = inheritedProtoView;
|
parent.inheritedElementBinder.nestedProtoView = inheritedProtoView;
|
||||||
|
|
||||||
|
// When current is a view root, the variable bindings are set to the *nested* proto view.
|
||||||
|
// The root view conceptually signifies a new "block scope" (the nested view), to which
|
||||||
|
// the variables are bound.
|
||||||
if (isPresent(parent.variableBindings)) {
|
if (isPresent(parent.variableBindings)) {
|
||||||
MapWrapper.forEach(parent.variableBindings, (mappedName, varName) => {
|
MapWrapper.forEach(parent.variableBindings, (mappedName, varName) => {
|
||||||
inheritedProtoView.bindVariable(varName, mappedName);
|
inheritedProtoView.bindVariable(varName, mappedName);
|
||||||
|
@ -49,6 +53,17 @@ export class ProtoViewBuilder extends CompileStep {
|
||||||
} else if (isPresent(parent)) {
|
} else if (isPresent(parent)) {
|
||||||
inheritedProtoView = parent.inheritedProtoView;
|
inheritedProtoView = parent.inheritedProtoView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The view's contextWithLocals needs to have a full set of variable names at construction time
|
||||||
|
// in order to prevent new variables from being set later in the lifecycle. Since we don't want
|
||||||
|
// to actually create variable bindings for the $implicit bindings, add to the
|
||||||
|
// protoContextLocals manually.
|
||||||
|
if (isPresent(current.variableBindings)) {
|
||||||
|
MapWrapper.forEach(current.variableBindings, (mappedName, varName) => {
|
||||||
|
MapWrapper.set(inheritedProtoView.protoContextLocals, mappedName, null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
current.inheritedProtoView = inheritedProtoView;
|
current.inheritedProtoView = inheritedProtoView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,16 @@ export class View {
|
||||||
var elementInjector = this.elementInjectors[i];
|
var elementInjector = this.elementInjectors[i];
|
||||||
if (isPresent(elementInjector)) {
|
if (isPresent(elementInjector)) {
|
||||||
elementInjector.instantiateDirectives(appInjector, shadowDomAppInjector, this.preBuiltObjects[i]);
|
elementInjector.instantiateDirectives(appInjector, shadowDomAppInjector, this.preBuiltObjects[i]);
|
||||||
|
|
||||||
|
// The exporting of $implicit is a special case. Since multiple elements will all export
|
||||||
|
// the different values as $implicit, directly assign $implicit bindings to the variable
|
||||||
|
// name.
|
||||||
|
var exportImplicitName = elementInjector.getExportImplicitName();
|
||||||
|
if (elementInjector.isExportingComponent()) {
|
||||||
|
this.context.set(exportImplicitName, elementInjector.getComponent());
|
||||||
|
} else if (elementInjector.isExportingElement()) {
|
||||||
|
this.context.set(exportImplicitName, elementInjector.getNgElement().domElement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPresent(componentDirective)) {
|
if (isPresent(componentDirective)) {
|
||||||
|
|
|
@ -133,6 +133,62 @@ export function main() {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should assign the component instance to a var-', (done) => {
|
||||||
|
compiler.compile(MyComp, el('<p><child-cmp var-alice></child-cmp></p>')).then((pv) => {
|
||||||
|
createView(pv);
|
||||||
|
|
||||||
|
expect(view.contextWithLocals).not.toBe(null);
|
||||||
|
expect(view.contextWithLocals.get('alice')).toBeAnInstanceOf(ChildComp);
|
||||||
|
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should assign two component instances each with a var-', (done) => {
|
||||||
|
var element = el('<p><child-cmp var-alice></child-cmp><child-cmp var-bob></p>');
|
||||||
|
|
||||||
|
compiler.compile(MyComp, element).then((pv) => {
|
||||||
|
createView(pv);
|
||||||
|
|
||||||
|
expect(view.contextWithLocals).not.toBe(null);
|
||||||
|
expect(view.contextWithLocals.get('alice')).toBeAnInstanceOf(ChildComp);
|
||||||
|
expect(view.contextWithLocals.get('bob')).toBeAnInstanceOf(ChildComp);
|
||||||
|
expect(view.contextWithLocals.get('alice')).not.toBe(view.contextWithLocals.get('bob'));
|
||||||
|
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should assign the component instance to a var- with shorthand syntax', (done) => {
|
||||||
|
compiler.compile(MyComp, el('<child-cmp #alice></child-cmp>')).then((pv) => {
|
||||||
|
createView(pv);
|
||||||
|
|
||||||
|
expect(view.contextWithLocals).not.toBe(null);
|
||||||
|
expect(view.contextWithLocals.get('alice')).toBeAnInstanceOf(ChildComp);
|
||||||
|
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should assign the element instance to a user-defined variable', (done) => {
|
||||||
|
// How is this supposed to work?
|
||||||
|
var element = el('<p></p>');
|
||||||
|
var div = el('<div var-alice></div>');
|
||||||
|
DOM.appendChild(div, el('<i>Hello</i>'));
|
||||||
|
DOM.appendChild(element, div);
|
||||||
|
|
||||||
|
compiler.compile(MyComp, element).then((pv) => {
|
||||||
|
createView(pv);
|
||||||
|
expect(view.contextWithLocals).not.toBe(null);
|
||||||
|
|
||||||
|
var value = view.contextWithLocals.get('alice');
|
||||||
|
expect(value).not.toBe(null);
|
||||||
|
expect(value.tagName).toEqual('DIV');
|
||||||
|
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,10 +34,24 @@ export function main() {
|
||||||
expect(MapWrapper.get(results[0].variableBindings, 'b')).toEqual('a');
|
expect(MapWrapper.get(results[0].variableBindings, 'b')).toEqual('a');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not allow var- syntax on non template elements', () => {
|
it('should store variable binding for a non-template element', () => {
|
||||||
expect( () => {
|
var results = createPipeline().process(el('<p var-george="washington"></p>'));
|
||||||
createPipeline().process(el('<div var-a="b"></div>'))
|
expect(MapWrapper.get(results[0].variableBindings, 'washington')).toEqual('george');
|
||||||
}).toThrowError('var-* is only allowed on <template> elements!');
|
});
|
||||||
|
|
||||||
|
it('should store variable binding for a non-template element using shorthand syntax', () => {
|
||||||
|
var results = createPipeline().process(el('<p #george="washington"></p>'));
|
||||||
|
expect(MapWrapper.get(results[0].variableBindings, 'washington')).toEqual('george');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should store a variable binding with an implicit value', () => {
|
||||||
|
var results = createPipeline().process(el('<p var-george></p>'));
|
||||||
|
expect(MapWrapper.get(results[0].variableBindings, '\$implicit')).toEqual('george');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should store a variable binding with an implicit value using shorthand syntax', () => {
|
||||||
|
var results = createPipeline().process(el('<p #george></p>'));
|
||||||
|
expect(MapWrapper.get(results[0].variableBindings, '\$implicit')).toEqual('george');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should detect () syntax', () => {
|
it('should detect () syntax', () => {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {describe, beforeEach, it, expect, iit, ddescribe, el} from 'angular2/test_lib';
|
import {describe, beforeEach, it, expect, iit, ddescribe, el} from 'angular2/test_lib';
|
||||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||||
import {DOM} from 'angular2/src/facade/dom';
|
import {DOM} from 'angular2/src/facade/dom';
|
||||||
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
import {List, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
import {ProtoElementInjectorBuilder} from 'angular2/src/core/compiler/pipeline/proto_element_injector_builder';
|
import {ProtoElementInjectorBuilder} from 'angular2/src/core/compiler/pipeline/proto_element_injector_builder';
|
||||||
import {CompilePipeline} from 'angular2/src/core/compiler/pipeline/compile_pipeline';
|
import {CompilePipeline} from 'angular2/src/core/compiler/pipeline/compile_pipeline';
|
||||||
|
@ -21,6 +21,11 @@ export function main() {
|
||||||
protoView = new ProtoView(null, null, null);
|
protoView = new ProtoView(null, null, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Create consts for an elements with a var- so that we can fake parsing the var into
|
||||||
|
// the CompileElement's variableBindings without actually doing any parsing.
|
||||||
|
var ELEMENT_WITH_VAR = el('<div var-name></div>');
|
||||||
|
var DIRECTIVE_ELEMENT_WITH_VAR = el('<div var-name directives></div>');
|
||||||
|
|
||||||
function createPipeline(directives = null) {
|
function createPipeline(directives = null) {
|
||||||
if (isBlank(directives)) {
|
if (isBlank(directives)) {
|
||||||
directives = [];
|
directives = [];
|
||||||
|
@ -30,12 +35,20 @@ export function main() {
|
||||||
if (isPresent(current.element.getAttribute('viewroot'))) {
|
if (isPresent(current.element.getAttribute('viewroot'))) {
|
||||||
current.isViewRoot = true;
|
current.isViewRoot = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPresent(current.element.getAttribute('directives'))) {
|
if (isPresent(current.element.getAttribute('directives'))) {
|
||||||
for (var i=0; i<directives.length; i++) {
|
for (var i=0; i<directives.length; i++) {
|
||||||
var dirMetadata = reader.read(directives[i]);
|
var dirMetadata = reader.read(directives[i]);
|
||||||
current.addDirective(dirMetadata);
|
current.addDirective(dirMetadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check only for the hard-coded var- attribute from ELEMENT_WITH_VAR test element.
|
||||||
|
if (isPresent(current.element.getAttribute('var-name'))) {
|
||||||
|
current.variableBindings = MapWrapper.create();
|
||||||
|
MapWrapper.set(current.variableBindings, '\$implicit', 'name');
|
||||||
|
}
|
||||||
|
|
||||||
current.inheritedProtoView = protoView;
|
current.inheritedProtoView = protoView;
|
||||||
}), protoElementInjectorBuilder]);
|
}), protoElementInjectorBuilder]);
|
||||||
}
|
}
|
||||||
|
@ -44,11 +57,16 @@ export function main() {
|
||||||
return protoElementInjectorBuilder.findArgsFor(protoElementInjector);
|
return protoElementInjectorBuilder.findArgsFor(protoElementInjector);
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should not create a ProtoElementInjector for elements without directives', () => {
|
it('should not create a ProtoElementInjector for elements without directives or vars', () => {
|
||||||
var results = createPipeline().process(el('<div></div>'));
|
var results = createPipeline().process(el('<div></div>'));
|
||||||
expect(results[0].inheritedProtoElementInjector).toBe(null);
|
expect(results[0].inheritedProtoElementInjector).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should create a ProtoElementInjector for elements with a variable binding', () => {
|
||||||
|
var results = createPipeline().process(ELEMENT_WITH_VAR);
|
||||||
|
expect(results[0].inheritedProtoElementInjector).toBeAnInstanceOf(ProtoElementInjector);
|
||||||
|
});
|
||||||
|
|
||||||
it('should create a ProtoElementInjector for elements directives', () => {
|
it('should create a ProtoElementInjector for elements directives', () => {
|
||||||
var directives = [SomeComponentDirective, SomeTemplateDirective, SomeDecoratorDirective];
|
var directives = [SomeComponentDirective, SomeTemplateDirective, SomeDecoratorDirective];
|
||||||
var results = createPipeline(directives).process(el('<div directives></div>'));
|
var results = createPipeline(directives).process(el('<div directives></div>'));
|
||||||
|
@ -57,7 +75,22 @@ export function main() {
|
||||||
expect(boundDirectives).toEqual(directives);
|
expect(boundDirectives).toEqual(directives);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should mark ProtoElementInjector for elements with component directives and use the ComponentDirective as first binding', () => {
|
it('should flag the ProtoElementInjector for exporting the component instance when a' +
|
||||||
|
'component has a var- declaration', () => {
|
||||||
|
var results = createPipeline([SomeComponentDirective]).process(DIRECTIVE_ELEMENT_WITH_VAR);
|
||||||
|
expect(results[0].inheritedProtoElementInjector.exportComponent).toBe(true);
|
||||||
|
expect(results[0].inheritedProtoElementInjector.exportElement).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should flag the ProtoElementInjector for exporting the element when a' +
|
||||||
|
'non-component element has a var- declaration', () => {
|
||||||
|
var results = createPipeline([SomeComponentDirective]).process(ELEMENT_WITH_VAR);
|
||||||
|
expect(results[0].inheritedProtoElementInjector.exportComponent).toBe(false);
|
||||||
|
expect(results[0].inheritedProtoElementInjector.exportElement).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should mark ProtoElementInjector for elements with component directives and use the ' +
|
||||||
|
'ComponentDirective as first binding', () => {
|
||||||
var directives = [SomeDecoratorDirective, SomeComponentDirective];
|
var directives = [SomeDecoratorDirective, SomeComponentDirective];
|
||||||
var results = createPipeline(directives).process(el('<div directives></div>'));
|
var results = createPipeline(directives).process(el('<div directives></div>'));
|
||||||
var creationArgs = getCreationArgs(results[0].inheritedProtoElementInjector);
|
var creationArgs = getCreationArgs(results[0].inheritedProtoElementInjector);
|
||||||
|
|
|
@ -62,6 +62,21 @@ export function main() {
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should mark variables in the proto view context locals', () => {
|
||||||
|
var element = el('<div viewroot><p var-binding></p></div>');
|
||||||
|
|
||||||
|
var results = createPipeline({
|
||||||
|
'var1': 'map1',
|
||||||
|
'var2': 'map2'
|
||||||
|
}).process(element);
|
||||||
|
|
||||||
|
var protoView = results[0].inheritedProtoView;
|
||||||
|
expect(protoView.protoContextLocals).toEqual(MapWrapper.createFromStringMap({
|
||||||
|
'map2': null,
|
||||||
|
'map1': null
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
describe('errors', () => {
|
describe('errors', () => {
|
||||||
|
|
||||||
it('should not allow multiple nested ProtoViews for the same parent element', () => {
|
it('should not allow multiple nested ProtoViews for the same parent element', () => {
|
||||||
|
@ -84,4 +99,4 @@ class MockStep extends CompileStep {
|
||||||
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
|
||||||
this.processClosure(parent, current, control);
|
this.processClosure(parent, current, control);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue