feat(query): added support for querying by var bindings
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
import {CONST, Type, stringify, isPresent} from 'angular2/src/facade/lang';
|
import {CONST, Type, stringify, isPresent, StringWrapper, isString} from 'angular2/src/facade/lang';
|
||||||
import {DependencyAnnotation} from 'angular2/src/di/annotations_impl';
|
import {DependencyAnnotation} from 'angular2/src/di/annotations_impl';
|
||||||
import {resolveForwardRef} from 'angular2/di';
|
import {resolveForwardRef} from 'angular2/di';
|
||||||
|
|
||||||
@ -55,12 +55,17 @@ export class Attribute extends DependencyAnnotation {
|
|||||||
@CONST()
|
@CONST()
|
||||||
export class Query extends DependencyAnnotation {
|
export class Query extends DependencyAnnotation {
|
||||||
descendants: boolean;
|
descendants: boolean;
|
||||||
constructor(private _selector:Type, {descendants = false}: {descendants?: boolean} = {}) {
|
constructor(private _selector: Type | string,
|
||||||
|
{descendants = false}: {descendants?: boolean} = {}) {
|
||||||
super();
|
super();
|
||||||
this.descendants = descendants;
|
this.descendants = descendants;
|
||||||
}
|
}
|
||||||
|
|
||||||
get selector() { return resolveForwardRef(this._selector); }
|
get selector() { return resolveForwardRef(this._selector); }
|
||||||
|
|
||||||
|
get isVarBindingQuery(): boolean { return isString(this.selector); }
|
||||||
|
|
||||||
|
get varBindings(): List<string> { return StringWrapper.split(this.selector, new RegExp(",")); }
|
||||||
|
|
||||||
toString() { return `@Query(${stringify(this.selector)})`; }
|
toString() { return `@Query(${stringify(this.selector)})`; }
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ export class ElementBinder {
|
|||||||
|
|
||||||
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.');
|
||||||
|
@ -393,7 +393,8 @@ export class ProtoElementInjector {
|
|||||||
_strategy: _ProtoElementInjectorStrategy;
|
_strategy: _ProtoElementInjectorStrategy;
|
||||||
|
|
||||||
static create(parent: ProtoElementInjector, index: number, bindings: List<ResolvedBinding>,
|
static create(parent: ProtoElementInjector, index: number, bindings: List<ResolvedBinding>,
|
||||||
firstBindingIsComponent: boolean, distanceToParent: number) {
|
firstBindingIsComponent: boolean, distanceToParent: number,
|
||||||
|
directiveVariableBindings: Map<string, number>) {
|
||||||
var bd = [];
|
var bd = [];
|
||||||
|
|
||||||
ProtoElementInjector._createDirectiveBindingData(bindings, bd, firstBindingIsComponent);
|
ProtoElementInjector._createDirectiveBindingData(bindings, bd, firstBindingIsComponent);
|
||||||
@ -401,7 +402,8 @@ export class ProtoElementInjector {
|
|||||||
ProtoElementInjector._createViewInjectorBindingData(bindings, bd);
|
ProtoElementInjector._createViewInjectorBindingData(bindings, bd);
|
||||||
}
|
}
|
||||||
ProtoElementInjector._createHostInjectorBindingData(bindings, bd, firstBindingIsComponent);
|
ProtoElementInjector._createHostInjectorBindingData(bindings, bd, firstBindingIsComponent);
|
||||||
return new ProtoElementInjector(parent, index, bd, distanceToParent, firstBindingIsComponent);
|
return new ProtoElementInjector(parent, index, bd, distanceToParent, firstBindingIsComponent,
|
||||||
|
directiveVariableBindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _createDirectiveBindingData(dirBindings: List<ResolvedBinding>,
|
private static _createDirectiveBindingData(dirBindings: List<ResolvedBinding>,
|
||||||
@ -450,7 +452,8 @@ 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,
|
||||||
|
public directiveVariableBindings: Map<string, number>) {
|
||||||
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);
|
||||||
@ -693,12 +696,15 @@ export class ElementInjector extends TreeNode<ElementInjector> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onAllChangesDone(): void {
|
onAllChangesDone(): void {
|
||||||
if (isPresent(this._query0) && this._query0.originator === this)
|
if (isPresent(this._query0) && this._query0.originator === this) {
|
||||||
this._query0.list.fireCallbacks();
|
this._query0.list.fireCallbacks();
|
||||||
if (isPresent(this._query1) && this._query1.originator === this)
|
}
|
||||||
|
if (isPresent(this._query1) && this._query1.originator === this) {
|
||||||
this._query1.list.fireCallbacks();
|
this._query1.list.fireCallbacks();
|
||||||
if (isPresent(this._query2) && this._query2.originator === this)
|
}
|
||||||
|
if (isPresent(this._query2) && this._query2.originator === this) {
|
||||||
this._query2.list.fireCallbacks();
|
this._query2.list.fireCallbacks();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hydrate(injector: Injector, host: ElementInjector, preBuiltObjects: PreBuiltObjects): void {
|
hydrate(injector: Injector, host: ElementInjector, preBuiltObjects: PreBuiltObjects): void {
|
||||||
@ -716,9 +722,22 @@ export class ElementInjector extends TreeNode<ElementInjector> {
|
|||||||
this._checkShadowDomAppInjector(this._shadowDomAppInjector);
|
this._checkShadowDomAppInjector(this._shadowDomAppInjector);
|
||||||
|
|
||||||
this._strategy.hydrate();
|
this._strategy.hydrate();
|
||||||
|
|
||||||
|
this._addVarBindingsToQueries();
|
||||||
|
|
||||||
this.hydrated = true;
|
this.hydrated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasVariableBinding(name: string): boolean {
|
||||||
|
var vb = this._proto.directiveVariableBindings;
|
||||||
|
return isPresent(vb) && MapWrapper.contains(vb, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
getVariableBinding(name: string): any {
|
||||||
|
var index = MapWrapper.get(this._proto.directiveVariableBindings, name);
|
||||||
|
return isPresent(index) ? this.getDirectiveAtIndex(<number>index) : this.getElementRef();
|
||||||
|
}
|
||||||
|
|
||||||
private _createShadowDomAppInjector(componentDirective: DirectiveBinding,
|
private _createShadowDomAppInjector(componentDirective: DirectiveBinding,
|
||||||
appInjector: Injector): Injector {
|
appInjector: Injector): Injector {
|
||||||
if (!ListWrapper.isEmpty(componentDirective.resolvedAppInjectables)) {
|
if (!ListWrapper.isEmpty(componentDirective.resolvedAppInjectables)) {
|
||||||
@ -752,6 +771,10 @@ export class ElementInjector extends TreeNode<ElementInjector> {
|
|||||||
return this._proto.hostActionAccessors;
|
return this._proto.hostActionAccessors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDirectiveVariableBindings(): Map<string, number> {
|
||||||
|
return this._proto.directiveVariableBindings;
|
||||||
|
}
|
||||||
|
|
||||||
getComponent(): any { return this._strategy.getComponent(); }
|
getComponent(): any { return this._strategy.getComponent(); }
|
||||||
|
|
||||||
getElementRef(): ElementRef {
|
getElementRef(): ElementRef {
|
||||||
@ -884,6 +907,23 @@ export class ElementInjector extends TreeNode<ElementInjector> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _addVarBindingsToQueries(): void {
|
||||||
|
this._addVarBindingsToQuery(this._query0);
|
||||||
|
this._addVarBindingsToQuery(this._query1);
|
||||||
|
this._addVarBindingsToQuery(this._query2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _addVarBindingsToQuery(queryRef: QueryRef): void {
|
||||||
|
if (isBlank(queryRef) || !queryRef.query.isVarBindingQuery) return;
|
||||||
|
|
||||||
|
var vb = queryRef.query.varBindings;
|
||||||
|
for (var i = 0; i < vb.length; ++i) {
|
||||||
|
if (this.hasVariableBinding(vb[i])) {
|
||||||
|
queryRef.list.add(this.getVariableBinding(vb[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private _createQueryRef(query: Query): void {
|
private _createQueryRef(query: Query): void {
|
||||||
var queryList = new QueryList<any>();
|
var queryList = new QueryList<any>();
|
||||||
if (isBlank(this._query0)) {
|
if (isBlank(this._query0)) {
|
||||||
@ -1454,13 +1494,32 @@ class QueryRef {
|
|||||||
|
|
||||||
visit(inj: ElementInjector, aggregator: any[]): void {
|
visit(inj: ElementInjector, aggregator: any[]): void {
|
||||||
if (isBlank(inj) || !inj._hasQuery(this)) return;
|
if (isBlank(inj) || !inj._hasQuery(this)) return;
|
||||||
if (inj.hasDirective(this.query.selector)) {
|
|
||||||
aggregator.push(inj.get(this.query.selector));
|
if (this.query.isVarBindingQuery) {
|
||||||
|
this._aggregateVariableBindings(inj, aggregator);
|
||||||
|
} else {
|
||||||
|
this._aggregateDirective(inj, aggregator);
|
||||||
}
|
}
|
||||||
|
|
||||||
var child = inj._head;
|
var child = inj._head;
|
||||||
while (isPresent(child)) {
|
while (isPresent(child)) {
|
||||||
this.visit(child, aggregator);
|
this.visit(child, aggregator);
|
||||||
child = child._next;
|
child = child._next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _aggregateVariableBindings(inj: ElementInjector, aggregator: List<any>): void {
|
||||||
|
var vb = this.query.varBindings;
|
||||||
|
for (var i = 0; i < vb.length; ++i) {
|
||||||
|
if (inj.hasVariableBinding(vb[i])) {
|
||||||
|
aggregator.push(inj.getVariableBinding(vb[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _aggregateDirective(inj: ElementInjector, aggregator: List<any>): void {
|
||||||
|
if (inj.hasDirective(this.query.selector)) {
|
||||||
|
aggregator.push(inj.get(this.query.selector));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,9 +336,13 @@ function _createProtoElementInjector(binderIndex, parentPeiWithDistance, renderE
|
|||||||
// so that, when hydrating, $implicit can be set to the element.
|
// so that, when hydrating, $implicit can be set to the element.
|
||||||
var hasVariables = MapWrapper.size(renderElementBinder.variableBindings) > 0;
|
var hasVariables = MapWrapper.size(renderElementBinder.variableBindings) > 0;
|
||||||
if (directiveBindings.length > 0 || hasVariables) {
|
if (directiveBindings.length > 0 || hasVariables) {
|
||||||
protoElementInjector = ProtoElementInjector.create(
|
var directiveVariableBindings =
|
||||||
parentPeiWithDistance.protoElementInjector, binderIndex, directiveBindings,
|
createDirectiveVariableBindings(renderElementBinder, directiveBindings);
|
||||||
isPresent(componentDirectiveBinding), parentPeiWithDistance.distance);
|
|
||||||
|
protoElementInjector =
|
||||||
|
ProtoElementInjector.create(parentPeiWithDistance.protoElementInjector, binderIndex,
|
||||||
|
directiveBindings, isPresent(componentDirectiveBinding),
|
||||||
|
parentPeiWithDistance.distance, directiveVariableBindings);
|
||||||
protoElementInjector.attributes = renderElementBinder.readAttributes;
|
protoElementInjector.attributes = renderElementBinder.readAttributes;
|
||||||
}
|
}
|
||||||
return protoElementInjector;
|
return protoElementInjector;
|
||||||
@ -351,12 +355,8 @@ function _createElementBinder(protoView, boundElementIndex, renderElementBinder,
|
|||||||
if (renderElementBinder.parentIndex !== -1) {
|
if (renderElementBinder.parentIndex !== -1) {
|
||||||
parent = protoView.elementBinders[renderElementBinder.parentIndex];
|
parent = protoView.elementBinders[renderElementBinder.parentIndex];
|
||||||
}
|
}
|
||||||
|
var elBinder = protoView.bindElement(parent, renderElementBinder.distanceToParent,
|
||||||
var directiveVariableBindings =
|
protoElementInjector, componentDirectiveBinding);
|
||||||
createDirectiveVariableBindings(renderElementBinder, directiveBindings);
|
|
||||||
var elBinder =
|
|
||||||
protoView.bindElement(parent, renderElementBinder.distanceToParent, 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
|
||||||
@ -371,7 +371,7 @@ function _createElementBinder(protoView, boundElementIndex, renderElementBinder,
|
|||||||
|
|
||||||
export function createDirectiveVariableBindings(
|
export function createDirectiveVariableBindings(
|
||||||
renderElementBinder: renderApi.ElementBinder,
|
renderElementBinder: renderApi.ElementBinder,
|
||||||
directiveBindings: List<DirectiveBinding>): Map<String, number> {
|
directiveBindings: List<DirectiveBinding>): Map<string, number> {
|
||||||
var directiveVariableBindings = MapWrapper.create();
|
var directiveVariableBindings = MapWrapper.create();
|
||||||
MapWrapper.forEach(renderElementBinder.variableBindings, (templateName, exportAs) => {
|
MapWrapper.forEach(renderElementBinder.variableBindings, (templateName, exportAs) => {
|
||||||
var dirIndex = _findDirectiveIndexByExportAs(renderElementBinder, directiveBindings, exportAs);
|
var dirIndex = _findDirectiveIndexByExportAs(renderElementBinder, directiveBindings, exportAs);
|
||||||
|
@ -177,11 +177,9 @@ 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 =
|
var elBinder = new ElementBinder(this.elementBinders.length, parent, distanceToParent,
|
||||||
new ElementBinder(this.elementBinders.length, parent, distanceToParent,
|
protoElementInjector, componentDirective);
|
||||||
protoElementInjector, directiveVariableBindings, componentDirective);
|
|
||||||
|
|
||||||
this.elementBinders.push(elBinder);
|
this.elementBinders.push(elBinder);
|
||||||
return elBinder;
|
return elBinder;
|
||||||
|
@ -149,28 +149,30 @@ 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._populateViewLocals(view, elementInjector);
|
||||||
this._setUpEventEmitters(view, elementInjector, i);
|
this._setUpEventEmitters(view, elementInjector, i);
|
||||||
this._setUpHostActions(view, elementInjector, i);
|
this._setUpHostActions(view, elementInjector, i);
|
||||||
|
|
||||||
if (isPresent(binder.directiveVariableBindings)) {
|
|
||||||
MapWrapper.forEach(binder.directiveVariableBindings, (directiveIndex, name) => {
|
|
||||||
if (isBlank(directiveIndex)) {
|
|
||||||
view.locals.set(name, elementInjector.getElementRef().domElement);
|
|
||||||
} else {
|
|
||||||
view.locals.set(name, elementInjector.getDirectiveAtIndex(directiveIndex));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
view.changeDetector.hydrate(view.context, view.locals, view);
|
view.changeDetector.hydrate(view.context, view.locals, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_populateViewLocals(view: viewModule.AppView, elementInjector: eli.ElementInjector): void {
|
||||||
|
if (isPresent(elementInjector.getDirectiveVariableBindings())) {
|
||||||
|
MapWrapper.forEach(elementInjector.getDirectiveVariableBindings(), (directiveIndex, name) => {
|
||||||
|
if (isBlank(directiveIndex)) {
|
||||||
|
view.locals.set(name, elementInjector.getElementRef().domElement);
|
||||||
|
} else {
|
||||||
|
view.locals.set(name, elementInjector.getDirectiveAtIndex(directiveIndex));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_getOrCreateViewContainer(parentView: viewModule.AppView, boundElementIndex: number) {
|
_getOrCreateViewContainer(parentView: viewModule.AppView, boundElementIndex: number) {
|
||||||
var viewContainer = parentView.viewContainers[boundElementIndex];
|
var viewContainer = parentView.viewContainers[boundElementIndex];
|
||||||
if (isBlank(viewContainer)) {
|
if (isBlank(viewContainer)) {
|
||||||
|
@ -481,11 +481,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, null, binding);
|
return new ElementBinder(0, null, 0, null, binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createViewportElementBinder(nestedProtoView) {
|
function createViewportElementBinder(nestedProtoView) {
|
||||||
var elBinder = new ElementBinder(0, null, 0, null, null, null);
|
var elBinder = new ElementBinder(0, null, 0, null, null);
|
||||||
elBinder.nestedProtoView = nestedProtoView;
|
elBinder.nestedProtoView = nestedProtoView;
|
||||||
return elBinder;
|
return elBinder;
|
||||||
}
|
}
|
||||||
|
@ -163,6 +163,12 @@ class NeedsQuery {
|
|||||||
constructor(@Query(CountingDirective) query: QueryList<CountingDirective>) { this.query = query; }
|
constructor(@Query(CountingDirective) query: QueryList<CountingDirective>) { this.query = query; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
class NeedsQueryByVarBindings {
|
||||||
|
query: QueryList<any>;
|
||||||
|
constructor(@Query("one,two") query: QueryList<any>) { this.query = query; }
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class NeedsElementRef {
|
class NeedsElementRef {
|
||||||
elementRef;
|
elementRef;
|
||||||
@ -229,13 +235,13 @@ export function main() {
|
|||||||
dynamicBindings.push(bind(i).toValue(i));
|
dynamicBindings.push(bind(i).toValue(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
function createPei(parent, index, bindings, distance = 1, hasShadowRoot = false) {
|
function createPei(parent, index, bindings, distance = 1, hasShadowRoot = false, dirVariableBindings = null) {
|
||||||
var directiveBinding = ListWrapper.map(bindings, b => {
|
var directiveBinding = ListWrapper.map(bindings, b => {
|
||||||
if (b instanceof DirectiveBinding) return b;
|
if (b instanceof DirectiveBinding) return b;
|
||||||
if (b instanceof Binding) return DirectiveBinding.createFromBinding(b, null);
|
if (b instanceof Binding) return DirectiveBinding.createFromBinding(b, null);
|
||||||
return DirectiveBinding.createFromType(b, null);
|
return DirectiveBinding.createFromType(b, null);
|
||||||
});
|
});
|
||||||
return ProtoElementInjector.create(parent, index, directiveBinding, hasShadowRoot, distance);
|
return ProtoElementInjector.create(parent, index, directiveBinding, hasShadowRoot, distance, dirVariableBindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
function humanize(tree: TreeNode<any>, names: List<List<any>>) {
|
function humanize(tree: TreeNode<any>, names: List<List<any>>) {
|
||||||
@ -248,10 +254,10 @@ export function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function injector(bindings, lightDomAppInjector = null, isComponent: boolean = false,
|
function injector(bindings, lightDomAppInjector = null, isComponent: boolean = false,
|
||||||
preBuiltObjects = null, attributes = null) {
|
preBuiltObjects = null, attributes = null, dirVariableBindings = null) {
|
||||||
if (isBlank(lightDomAppInjector)) lightDomAppInjector = appInjector;
|
if (isBlank(lightDomAppInjector)) lightDomAppInjector = appInjector;
|
||||||
|
|
||||||
var proto = createPei(null, 0, bindings, 0, isComponent);
|
var proto = createPei(null, 0, bindings, 0, isComponent, dirVariableBindings);
|
||||||
proto.attributes = attributes;
|
proto.attributes = attributes;
|
||||||
|
|
||||||
var inj = proto.instantiate(null);
|
var inj = proto.instantiate(null);
|
||||||
@ -942,7 +948,7 @@ export function main() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('directive queries', () => {
|
describe('queries', () => {
|
||||||
var preBuildObjects = defaultPreBuiltObjects;
|
var preBuildObjects = defaultPreBuiltObjects;
|
||||||
beforeEach(() => { _constructionCount = 0; });
|
beforeEach(() => { _constructionCount = 0; });
|
||||||
|
|
||||||
@ -963,9 +969,39 @@ export function main() {
|
|||||||
|
|
||||||
it('should contain directives on the same injector', () => {
|
it('should contain directives on the same injector', () => {
|
||||||
var inj = injector(ListWrapper.concat([NeedsQuery, CountingDirective], extraBindings), null,
|
var inj = injector(ListWrapper.concat([NeedsQuery, CountingDirective], extraBindings), null,
|
||||||
false, preBuildObjects);
|
false, preBuildObjects);
|
||||||
|
|
||||||
expectDirectives(inj.get(NeedsQuery).query, CountingDirective, [0]);
|
expectDirectives(inj.get(NeedsQuery).query, CountingDirective, [0]);
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should contain the element when no directives are bound to the var binding', () => {
|
||||||
|
var dirs = [NeedsQueryByVarBindings];
|
||||||
|
|
||||||
|
var dirVariableBindings = MapWrapper.createFromStringMap({
|
||||||
|
"one": null // element
|
||||||
|
});
|
||||||
|
|
||||||
|
var inj = injector(ListWrapper.concat(dirs, extraBindings), null,
|
||||||
|
false, preBuildObjects, null, dirVariableBindings);
|
||||||
|
|
||||||
|
expect(inj.get(NeedsQueryByVarBindings).query.first).toBeAnInstanceOf(ElementRef);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should contain directives on the same injector when querying by variable bindings' +
|
||||||
|
'in the order of var bindings specified in the query', () => {
|
||||||
|
var dirs = [NeedsQueryByVarBindings, NeedsDirective, SimpleDirective];
|
||||||
|
|
||||||
|
var dirVariableBindings = MapWrapper.createFromStringMap({
|
||||||
|
"one": 2, // 2 is the index of SimpleDirective
|
||||||
|
"two": 1 // 1 is the index of NeedsDirective
|
||||||
|
});
|
||||||
|
|
||||||
|
var inj = injector(ListWrapper.concat(dirs, extraBindings), null,
|
||||||
|
false, preBuildObjects, null, dirVariableBindings);
|
||||||
|
|
||||||
|
// NeedsQueryByVarBindings queries "one,two", so SimpleDirective should be before NeedsDirective
|
||||||
|
expect(inj.get(NeedsQueryByVarBindings).query.first).toBeAnInstanceOf(SimpleDirective);
|
||||||
|
expect(inj.get(NeedsQueryByVarBindings).query.last).toBeAnInstanceOf(NeedsDirective);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Dart's restriction on static types in (a is A) makes this feature hard to implement.
|
// Dart's restriction on static types in (a is A) makes this feature hard to implement.
|
||||||
|
@ -26,154 +26,247 @@ export function main() {
|
|||||||
BrowserDomAdapter.makeCurrent();
|
BrowserDomAdapter.makeCurrent();
|
||||||
describe('Query API', () => {
|
describe('Query API', () => {
|
||||||
|
|
||||||
it('should contain all direct child directives in the light dom',
|
describe("querying by directive type", () => {
|
||||||
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
it('should contain all direct child directives in the light dom',
|
||||||
var template = '<div text="1"></div>' +
|
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
||||||
'<needs-query text="2"><div text="3">' +
|
var template = '<div text="1"></div>' +
|
||||||
'<div text="too-deep"></div>' +
|
'<needs-query text="2"><div text="3">' +
|
||||||
'</div></needs-query>' +
|
'<div text="too-deep"></div>' +
|
||||||
'<div text="4"></div>';
|
'</div></needs-query>' +
|
||||||
|
'<div text="4"></div>';
|
||||||
|
|
||||||
tb.createView(MyComp, {html: template})
|
tb.createView(MyComp, {html: template})
|
||||||
.then((view) => {
|
.then((view) => {
|
||||||
view.detectChanges();
|
view.detectChanges();
|
||||||
expect(view.rootNodes).toHaveText('2|3|');
|
expect(view.rootNodes).toHaveText('2|3|');
|
||||||
|
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should contain all directives in the light dom when descendants flag is used',
|
|
||||||
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
|
||||||
var template = '<div text="1"></div>' +
|
|
||||||
'<needs-query-desc text="2"><div text="3">' +
|
|
||||||
'<div text="4"></div>' +
|
|
||||||
'</div></needs-query-desc>' +
|
|
||||||
'<div text="5"></div>';
|
|
||||||
|
|
||||||
tb.createView(MyComp, {html: template})
|
|
||||||
.then((view) => {
|
|
||||||
view.detectChanges();
|
|
||||||
expect(view.rootNodes).toHaveText('2|3|4|');
|
|
||||||
|
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should contain all directives in the light dom',
|
|
||||||
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
|
||||||
var template = '<div text="1"></div>' +
|
|
||||||
'<needs-query text="2"><div text="3"></div></needs-query>' +
|
|
||||||
'<div text="4"></div>';
|
|
||||||
|
|
||||||
tb.createView(MyComp, {html: template})
|
|
||||||
.then((view) => {
|
|
||||||
view.detectChanges();
|
|
||||||
expect(view.rootNodes).toHaveText('2|3|');
|
|
||||||
|
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
// TODO(rado): The test below should be using descendants: false,
|
|
||||||
// but due to a bug with how injectors are hooked up query considers the
|
|
||||||
// directives to be distances 2 instead of direct children.
|
|
||||||
it('should reflect dynamically inserted directives',
|
|
||||||
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
|
||||||
var template =
|
|
||||||
'<div text="1"></div>' +
|
|
||||||
'<needs-query-desc text="2"><div *ng-if="shouldShow" [text]="\'3\'"></div></needs-query-desc>' +
|
|
||||||
'<div text="4"></div>';
|
|
||||||
|
|
||||||
tb.createView(MyComp, {html: template})
|
|
||||||
.then((view) => {
|
|
||||||
|
|
||||||
view.detectChanges();
|
|
||||||
expect(view.rootNodes).toHaveText('2|');
|
|
||||||
|
|
||||||
view.context.shouldShow = true;
|
|
||||||
view.detectChanges();
|
|
||||||
expect(view.rootNodes).toHaveText('2|3|');
|
|
||||||
|
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should reflect moved directives',
|
|
||||||
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
|
||||||
var template =
|
|
||||||
'<div text="1"></div>' +
|
|
||||||
'<needs-query-desc text="2"><div *ng-for="var i of list" [text]="i"></div></needs-query-desc>' +
|
|
||||||
'<div text="4"></div>';
|
|
||||||
|
|
||||||
tb.createView(MyComp, {html: template})
|
|
||||||
.then((view) => {
|
|
||||||
view.detectChanges();
|
|
||||||
view.detectChanges();
|
|
||||||
|
|
||||||
expect(view.rootNodes).toHaveText('2|1d|2d|3d|');
|
|
||||||
|
|
||||||
view.context.list = ['3d', '2d'];
|
|
||||||
view.detectChanges();
|
|
||||||
view.detectChanges();
|
|
||||||
expect(view.rootNodes).toHaveText('2|3d|2d|');
|
|
||||||
|
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should notify query on change',
|
|
||||||
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
|
||||||
var template = '<needs-query-desc #q>' +
|
|
||||||
'<div text="1"></div>' +
|
|
||||||
'<div *ng-if="shouldShow" text="2"></div>' +
|
|
||||||
'</needs-query-desc>';
|
|
||||||
|
|
||||||
tb.createView(MyComp, {html: template})
|
|
||||||
.then((view) => {
|
|
||||||
var q = view.rawView.locals.get("q");
|
|
||||||
view.detectChanges();
|
|
||||||
|
|
||||||
q.query.onChange(() => {
|
|
||||||
expect(q.query.first.text).toEqual("1");
|
|
||||||
expect(q.query.last.text).toEqual("2");
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
view.context.shouldShow = true;
|
it('should contain all directives in the light dom when descendants flag is used',
|
||||||
view.detectChanges();
|
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
||||||
});
|
var template = '<div text="1"></div>' +
|
||||||
}));
|
'<needs-query-desc text="2"><div text="3">' +
|
||||||
|
'<div text="4"></div>' +
|
||||||
|
'</div></needs-query-desc>' +
|
||||||
|
'<div text="5"></div>';
|
||||||
|
|
||||||
it("should notify child's query before notifying parent's query",
|
tb.createView(MyComp, {html: template})
|
||||||
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
.then((view) => {
|
||||||
var template = '<needs-query-desc #q1>' +
|
view.detectChanges();
|
||||||
'<needs-query-desc #q2>' +
|
expect(view.rootNodes).toHaveText('2|3|4|');
|
||||||
'<div text="1"></div>' +
|
|
||||||
'</needs-query-desc>' +
|
|
||||||
'</needs-query-desc>';
|
|
||||||
|
|
||||||
tb.createView(MyComp, {html: template})
|
|
||||||
.then((view) => {
|
|
||||||
var q1 = view.rawView.locals.get("q1");
|
|
||||||
var q2 = view.rawView.locals.get("q2");
|
|
||||||
|
|
||||||
var firedQ2 = false;
|
|
||||||
|
|
||||||
q2.query.onChange(() => { firedQ2 = true; });
|
|
||||||
q1.query.onChange(() => {
|
|
||||||
expect(firedQ2).toBe(true);
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
view.detectChanges();
|
it('should contain all directives in the light dom',
|
||||||
});
|
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
||||||
}));
|
var template = '<div text="1"></div>' +
|
||||||
|
'<needs-query text="2"><div text="3"></div></needs-query>' +
|
||||||
|
'<div text="4"></div>';
|
||||||
|
|
||||||
|
tb.createView(MyComp, {html: template})
|
||||||
|
.then((view) => {
|
||||||
|
view.detectChanges();
|
||||||
|
expect(view.rootNodes).toHaveText('2|3|');
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
// TODO(rado): The test below should be using descendants: false,
|
||||||
|
// but due to a bug with how injectors are hooked up query considers the
|
||||||
|
// directives to be distances 2 instead of direct children.
|
||||||
|
it('should reflect dynamically inserted directives',
|
||||||
|
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
||||||
|
var template =
|
||||||
|
'<div text="1"></div>' +
|
||||||
|
'<needs-query-desc text="2"><div *ng-if="shouldShow" [text]="\'3\'"></div></needs-query-desc>' +
|
||||||
|
'<div text="4"></div>';
|
||||||
|
|
||||||
|
tb.createView(MyComp, {html: template})
|
||||||
|
.then((view) => {
|
||||||
|
|
||||||
|
view.detectChanges();
|
||||||
|
expect(view.rootNodes).toHaveText('2|');
|
||||||
|
|
||||||
|
view.context.shouldShow = true;
|
||||||
|
view.detectChanges();
|
||||||
|
expect(view.rootNodes).toHaveText('2|3|');
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should reflect moved directives',
|
||||||
|
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
||||||
|
var template =
|
||||||
|
'<div text="1"></div>' +
|
||||||
|
'<needs-query-desc text="2"><div *ng-for="var i of list" [text]="i"></div></needs-query-desc>' +
|
||||||
|
'<div text="4"></div>';
|
||||||
|
|
||||||
|
tb.createView(MyComp, {html: template})
|
||||||
|
.then((view) => {
|
||||||
|
view.detectChanges();
|
||||||
|
|
||||||
|
expect(view.rootNodes).toHaveText('2|1d|2d|3d|');
|
||||||
|
|
||||||
|
view.context.list = ['3d', '2d'];
|
||||||
|
view.detectChanges();
|
||||||
|
view.detectChanges();
|
||||||
|
expect(view.rootNodes).toHaveText('2|3d|2d|');
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("onChange", () => {
|
||||||
|
it('should notify query on change',
|
||||||
|
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
||||||
|
var template = '<needs-query-desc #q>' +
|
||||||
|
'<div text="1"></div>' +
|
||||||
|
'<div *ng-if="shouldShow" text="2"></div>' +
|
||||||
|
'</needs-query-desc>';
|
||||||
|
|
||||||
|
tb.createView(MyComp, {html: template})
|
||||||
|
.then((view) => {
|
||||||
|
var q = view.rawView.locals.get("q");
|
||||||
|
view.detectChanges();
|
||||||
|
|
||||||
|
q.query.onChange(() => {
|
||||||
|
expect(q.query.first.text).toEqual("1");
|
||||||
|
expect(q.query.last.text).toEqual("2");
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
|
||||||
|
view.context.shouldShow = true;
|
||||||
|
view.detectChanges();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it("should notify child's query before notifying parent's query",
|
||||||
|
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
||||||
|
var template = '<needs-query-desc #q1>' +
|
||||||
|
'<needs-query-desc #q2>' +
|
||||||
|
'<div text="1"></div>' +
|
||||||
|
'</needs-query-desc>' +
|
||||||
|
'</needs-query-desc>';
|
||||||
|
|
||||||
|
tb.createView(MyComp, {html: template})
|
||||||
|
.then((view) => {
|
||||||
|
var q1 = view.rawView.locals.get("q1");
|
||||||
|
var q2 = view.rawView.locals.get("q2");
|
||||||
|
|
||||||
|
var firedQ2 = false;
|
||||||
|
|
||||||
|
q2.query.onChange(() => { firedQ2 = true; });
|
||||||
|
q1.query.onChange(() => {
|
||||||
|
expect(firedQ2).toBe(true);
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
|
||||||
|
view.detectChanges();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("querying by var binding", () => {
|
||||||
|
it('should contain all the child directives in the light dom with the given var binding',
|
||||||
|
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
||||||
|
var template =
|
||||||
|
'<needs-query-by-var-binding #q>' +
|
||||||
|
'<div *ng-for="#item of list" [text]="item" #text-label="textDir"></div>' +
|
||||||
|
'</needs-query-by-var-binding>';
|
||||||
|
|
||||||
|
tb.createView(MyComp, {html: template})
|
||||||
|
.then((view) => {
|
||||||
|
var q = view.rawView.locals.get("q");
|
||||||
|
|
||||||
|
view.context.list = ['1d', '2d'];
|
||||||
|
|
||||||
|
view.detectChanges();
|
||||||
|
|
||||||
|
expect(q.query.first.text).toEqual("1d");
|
||||||
|
expect(q.query.last.text).toEqual("2d");
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should support querying by multiple var bindings',
|
||||||
|
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
||||||
|
var template = '<needs-query-by-var-bindings #q>' +
|
||||||
|
'<div text="one" #text-label1="textDir"></div>' +
|
||||||
|
'<div text="two" #text-label2="textDir"></div>' +
|
||||||
|
'</needs-query-by-var-bindings>';
|
||||||
|
|
||||||
|
tb.createView(MyComp, {html: template})
|
||||||
|
.then((view) => {
|
||||||
|
var q = view.rawView.locals.get("q");
|
||||||
|
view.detectChanges();
|
||||||
|
|
||||||
|
expect(q.query.first.text).toEqual("one");
|
||||||
|
expect(q.query.last.text).toEqual("two");
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should reflect dynamically inserted directives',
|
||||||
|
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
||||||
|
var template =
|
||||||
|
'<needs-query-by-var-binding #q>' +
|
||||||
|
'<div *ng-for="#item of list" [text]="item" #text-label="textDir"></div>' +
|
||||||
|
'</needs-query-by-var-binding>';
|
||||||
|
|
||||||
|
tb.createView(MyComp, {html: template})
|
||||||
|
.then((view) => {
|
||||||
|
var q = view.rawView.locals.get("q");
|
||||||
|
|
||||||
|
view.context.list = ['1d', '2d'];
|
||||||
|
|
||||||
|
view.detectChanges();
|
||||||
|
|
||||||
|
view.context.list = ['2d', '1d'];
|
||||||
|
|
||||||
|
view.detectChanges();
|
||||||
|
|
||||||
|
expect(q.query.last.text).toEqual("1d");
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should contain all the elements in the light dom with the given var binding',
|
||||||
|
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => {
|
||||||
|
var template = '<needs-query-by-var-binding #q>' +
|
||||||
|
'<div template="ng-for: #item of list">' +
|
||||||
|
'<div #text-label>{{item}}</div>' +
|
||||||
|
'</div>' +
|
||||||
|
'</needs-query-by-var-binding>';
|
||||||
|
|
||||||
|
tb.createView(MyComp, {html: template})
|
||||||
|
.then((view) => {
|
||||||
|
var q = view.rawView.locals.get("q");
|
||||||
|
|
||||||
|
view.context.list = ['1d', '2d'];
|
||||||
|
|
||||||
|
view.detectChanges();
|
||||||
|
|
||||||
|
expect(q.query.first.domElement).toHaveText("1d");
|
||||||
|
expect(q.query.last.domElement).toHaveText("2d");
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Directive({selector: '[text]', properties: ['text']})
|
@Directive({selector: '[text]', properties: ['text'], exportAs: 'textDir'})
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class TextDirective {
|
class TextDirective {
|
||||||
text: string;
|
text: string;
|
||||||
@ -198,8 +291,38 @@ class NeedsQueryDesc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component({selector: 'needs-query-by-var-binding'})
|
||||||
|
@View({directives: [], template: '<content>'})
|
||||||
|
@Injectable()
|
||||||
|
class NeedsQueryByLabel {
|
||||||
|
query: QueryList<any>;
|
||||||
|
constructor(@Query("textLabel", {descendants: true}) query: QueryList<any>) {
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({selector: 'needs-query-by-var-bindings'})
|
||||||
|
@View({directives: [], template: '<content>'})
|
||||||
|
@Injectable()
|
||||||
|
class NeedsQueryByTwoLabels {
|
||||||
|
query: QueryList<any>;
|
||||||
|
constructor(@Query("textLabel1,textLabel2", {descendants: true}) query: QueryList<any>) {
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Component({selector: 'my-comp'})
|
@Component({selector: 'my-comp'})
|
||||||
@View({directives: [NeedsQuery, NeedsQueryDesc, TextDirective, NgIf, NgFor]})
|
@View({
|
||||||
|
directives: [
|
||||||
|
NeedsQuery,
|
||||||
|
NeedsQueryDesc,
|
||||||
|
NeedsQueryByLabel,
|
||||||
|
NeedsQueryByTwoLabels,
|
||||||
|
TextDirective,
|
||||||
|
NgIf,
|
||||||
|
NgFor
|
||||||
|
]
|
||||||
|
})
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class MyComp {
|
class MyComp {
|
||||||
shouldShow: boolean;
|
shouldShow: boolean;
|
||||||
|
@ -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, null); }
|
function createEmptyElBinder() { return new ElementBinder(0, null, 0, 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, null, binding);
|
var binder = new ElementBinder(0, null, 0, 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, null); }
|
function createEmptyElBinder() { return new ElementBinder(0, null, 0, 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, null, binding);
|
var binder = new ElementBinder(0, null, 0, null, binding);
|
||||||
binder.nestedProtoView = nestedProtoView;
|
binder.nestedProtoView = nestedProtoView;
|
||||||
return binder;
|
return binder;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ export function main() {
|
|||||||
DirectiveBinding.createFromType(B, null),
|
DirectiveBinding.createFromType(B, null),
|
||||||
DirectiveBinding.createFromType(C, null)
|
DirectiveBinding.createFromType(C, null)
|
||||||
];
|
];
|
||||||
var proto = ProtoElementInjector.create(null, 0, bindings, false, 0);
|
var proto = ProtoElementInjector.create(null, 0, bindings, false, 0, null);
|
||||||
var elementInjector = proto.instantiate(null);
|
var elementInjector = proto.instantiate(null);
|
||||||
|
|
||||||
function instantiate() {
|
function instantiate() {
|
||||||
|
Reference in New Issue
Block a user