refactor(core): add `Query.read` and remove `DynamicComponentLoader.loadIntoLocation`.
This adds the feature for `@ViewChild`/`@ViewChildren`/`@ContentChild`/`@ContentChildren` to define what to read from the queried element. E.g. `@ViewChild(`someVar`, read: ViewContainerRef)` will locate the element with a variable `someVar` on it and return a `ViewContainerRef` for it. Background: With this change, Angular knows exactly at which elements there will be `ViewConainerRef`s as the user has to ask explicitly of them. This simplifies codegen and will make converting Angular templates into server side templates simpler as well. BREAKING CHANGE: - `DynamicComponentLoader.loadIntoLocation` has been removed. Use `@ViewChild(‘myVar’, read: ViewContainerRef)` to get hold of a `ViewContainerRef` at an element with variable `myVar`. - `DynamicComponentLoader.loadNextToLocation` now takes a `ViewContainerRef` instead of an `ElementRef`. - `AppViewManager` is renamed into `ViewUtils` and is a mere private utility service.
This commit is contained in:
parent
c06b0a2371
commit
efbd446d18
|
@ -13,7 +13,12 @@ import {
|
||||||
isArray
|
isArray
|
||||||
} from 'angular2/src/facade/lang';
|
} from 'angular2/src/facade/lang';
|
||||||
import {unimplemented, BaseException} from 'angular2/src/facade/exceptions';
|
import {unimplemented, BaseException} from 'angular2/src/facade/exceptions';
|
||||||
import {StringMapWrapper, MapWrapper, SetWrapper} from 'angular2/src/facade/collection';
|
import {
|
||||||
|
StringMapWrapper,
|
||||||
|
MapWrapper,
|
||||||
|
SetWrapper,
|
||||||
|
ListWrapper
|
||||||
|
} from 'angular2/src/facade/collection';
|
||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
CHANGE_DETECTION_STRATEGY_VALUES
|
CHANGE_DETECTION_STRATEGY_VALUES
|
||||||
|
@ -414,17 +419,20 @@ export class CompileQueryMetadata {
|
||||||
descendants: boolean;
|
descendants: boolean;
|
||||||
first: boolean;
|
first: boolean;
|
||||||
propertyName: string;
|
propertyName: string;
|
||||||
|
read: CompileTokenMetadata;
|
||||||
|
|
||||||
constructor({selectors, descendants, first, propertyName}: {
|
constructor({selectors, descendants, first, propertyName, read}: {
|
||||||
selectors?: Array<CompileTokenMetadata>,
|
selectors?: Array<CompileTokenMetadata>,
|
||||||
descendants?: boolean,
|
descendants?: boolean,
|
||||||
first?: boolean,
|
first?: boolean,
|
||||||
propertyName?: string
|
propertyName?: string,
|
||||||
|
read?: CompileTokenMetadata
|
||||||
} = {}) {
|
} = {}) {
|
||||||
this.selectors = selectors;
|
this.selectors = selectors;
|
||||||
this.descendants = normalizeBool(descendants);
|
this.descendants = normalizeBool(descendants);
|
||||||
this.first = normalizeBool(first);
|
this.first = normalizeBool(first);
|
||||||
this.propertyName = propertyName;
|
this.propertyName = propertyName;
|
||||||
|
this.read = read;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(data: {[key: string]: any}): CompileQueryMetadata {
|
static fromJson(data: {[key: string]: any}): CompileQueryMetadata {
|
||||||
|
@ -432,7 +440,8 @@ export class CompileQueryMetadata {
|
||||||
selectors: _arrayFromJson(data['selectors'], CompileTokenMetadata.fromJson),
|
selectors: _arrayFromJson(data['selectors'], CompileTokenMetadata.fromJson),
|
||||||
descendants: data['descendants'],
|
descendants: data['descendants'],
|
||||||
first: data['first'],
|
first: data['first'],
|
||||||
propertyName: data['propertyName']
|
propertyName: data['propertyName'],
|
||||||
|
read: _objFromJson(data['read'], CompileTokenMetadata.fromJson)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,7 +450,8 @@ export class CompileQueryMetadata {
|
||||||
'selectors': _arrayToJson(this.selectors),
|
'selectors': _arrayToJson(this.selectors),
|
||||||
'descendants': this.descendants,
|
'descendants': this.descendants,
|
||||||
'first': this.first,
|
'first': this.first,
|
||||||
'propertyName': this.propertyName
|
'propertyName': this.propertyName,
|
||||||
|
'read': _objToJson(this.read)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import {CompileIdentifierMetadata, CompileTokenMetadata} from './compile_metadat
|
||||||
import {AppView} from 'angular2/src/core/linker/view';
|
import {AppView} from 'angular2/src/core/linker/view';
|
||||||
import {StaticNodeDebugInfo, DebugContext} from 'angular2/src/core/linker/debug_context';
|
import {StaticNodeDebugInfo, DebugContext} from 'angular2/src/core/linker/debug_context';
|
||||||
import {
|
import {
|
||||||
|
ViewUtils,
|
||||||
flattenNestedViewRenderNodes,
|
flattenNestedViewRenderNodes,
|
||||||
interpolate,
|
interpolate,
|
||||||
checkBinding
|
checkBinding
|
||||||
|
@ -15,7 +16,6 @@ import {
|
||||||
ChangeDetectorState,
|
ChangeDetectorState,
|
||||||
ChangeDetectionStrategy
|
ChangeDetectionStrategy
|
||||||
} from 'angular2/src/core/change_detection/change_detection';
|
} from 'angular2/src/core/change_detection/change_detection';
|
||||||
import {AppViewManager_} from 'angular2/src/core/linker/view_manager';
|
|
||||||
import {AppElement} from 'angular2/src/core/linker/element';
|
import {AppElement} from 'angular2/src/core/linker/element';
|
||||||
import {ElementRef} from 'angular2/src/core/linker/element_ref';
|
import {ElementRef} from 'angular2/src/core/linker/element_ref';
|
||||||
import {ViewContainerRef} from 'angular2/src/core/linker/view_container_ref';
|
import {ViewContainerRef} from 'angular2/src/core/linker/view_container_ref';
|
||||||
|
@ -34,7 +34,7 @@ var CD_MODULE_URL = 'asset:angular2/lib/src/core/change_detection/change_detecti
|
||||||
// Reassign the imports to different variables so we can
|
// Reassign the imports to different variables so we can
|
||||||
// define static variables with the name of the import.
|
// define static variables with the name of the import.
|
||||||
// (only needed for Dart).
|
// (only needed for Dart).
|
||||||
var impAppViewManager_ = AppViewManager_;
|
var impViewUtils = ViewUtils;
|
||||||
var impAppView = AppView;
|
var impAppView = AppView;
|
||||||
var impDebugContext = DebugContext;
|
var impDebugContext = DebugContext;
|
||||||
var impAppElement = AppElement;
|
var impAppElement = AppElement;
|
||||||
|
@ -61,10 +61,10 @@ var impInterpolate = interpolate;
|
||||||
var impCheckBinding = checkBinding;
|
var impCheckBinding = checkBinding;
|
||||||
|
|
||||||
export class Identifiers {
|
export class Identifiers {
|
||||||
static AppViewManager_ = new CompileIdentifierMetadata({
|
static ViewUtils = new CompileIdentifierMetadata({
|
||||||
name: 'AppViewManager_',
|
name: 'ViewUtils',
|
||||||
moduleUrl: 'asset:angular2/lib/src/core/linker/view_manager' + MODULE_SUFFIX,
|
moduleUrl: 'asset:angular2/lib/src/core/linker/view_utils' + MODULE_SUFFIX,
|
||||||
runtime: impAppViewManager_
|
runtime: impViewUtils
|
||||||
});
|
});
|
||||||
static AppView = new CompileIdentifierMetadata(
|
static AppView = new CompileIdentifierMetadata(
|
||||||
{name: 'AppView', moduleUrl: APP_VIEW_MODULE_URL, runtime: impAppView});
|
{name: 'AppView', moduleUrl: APP_VIEW_MODULE_URL, runtime: impAppView});
|
||||||
|
|
|
@ -65,28 +65,42 @@ export class ProviderElementContext {
|
||||||
private _seenProviders = new CompileTokenMap<boolean>();
|
private _seenProviders = new CompileTokenMap<boolean>();
|
||||||
private _allProviders: CompileTokenMap<ProviderAst>;
|
private _allProviders: CompileTokenMap<ProviderAst>;
|
||||||
private _attrs: {[key: string]: string};
|
private _attrs: {[key: string]: string};
|
||||||
|
private _hasViewContainer: boolean = false;
|
||||||
|
|
||||||
constructor(private _viewContext: ProviderViewContext, private _parent: ProviderElementContext,
|
constructor(private _viewContext: ProviderViewContext, private _parent: ProviderElementContext,
|
||||||
private _isViewRoot: boolean, private _directiveAsts: DirectiveAst[],
|
private _isViewRoot: boolean, private _directiveAsts: DirectiveAst[],
|
||||||
attrs: AttrAst[], private _sourceSpan: ParseSourceSpan) {
|
attrs: AttrAst[], vars: VariableAst[], private _sourceSpan: ParseSourceSpan) {
|
||||||
this._attrs = {};
|
this._attrs = {};
|
||||||
attrs.forEach((attrAst) => this._attrs[attrAst.name] = attrAst.value);
|
attrs.forEach((attrAst) => this._attrs[attrAst.name] = attrAst.value);
|
||||||
var directivesMeta = _directiveAsts.map(directiveAst => directiveAst.directive);
|
var directivesMeta = _directiveAsts.map(directiveAst => directiveAst.directive);
|
||||||
this._allProviders =
|
this._allProviders =
|
||||||
_resolveProvidersFromDirectives(directivesMeta, _sourceSpan, _viewContext.errors);
|
_resolveProvidersFromDirectives(directivesMeta, _sourceSpan, _viewContext.errors);
|
||||||
this._contentQueries = _getContentQueries(directivesMeta);
|
this._contentQueries = _getContentQueries(directivesMeta);
|
||||||
|
var queriedTokens = new CompileTokenMap<boolean>();
|
||||||
|
this._allProviders.values().forEach(
|
||||||
|
(provider) => { this._addQueryReadsTo(provider.token, queriedTokens); });
|
||||||
|
vars.forEach((varAst) => {
|
||||||
|
var varToken = new CompileTokenMetadata({value: varAst.name});
|
||||||
|
this._addQueryReadsTo(varToken, queriedTokens);
|
||||||
|
});
|
||||||
|
if (isPresent(queriedTokens.get(identifierToken(Identifiers.ViewContainerRef)))) {
|
||||||
|
this._hasViewContainer = true;
|
||||||
|
}
|
||||||
|
|
||||||
// create the providers that we know are eager first
|
// create the providers that we know are eager first
|
||||||
this._allProviders.values().forEach((provider) => {
|
this._allProviders.values().forEach((provider) => {
|
||||||
if (provider.eager || this.isQueried(provider.token)) {
|
var eager = provider.eager || isPresent(queriedTokens.get(provider.token));
|
||||||
this._getLocalProvider(provider.providerType, provider.token, true);
|
if (eager) {
|
||||||
|
this._getOrCreateLocalProvider(provider.providerType, provider.token, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
afterElement() {
|
afterElement() {
|
||||||
// collect lazy providers
|
// collect lazy providers
|
||||||
this._allProviders.values().forEach(
|
this._allProviders.values().forEach((provider) => {
|
||||||
(provider) => { this._getLocalProvider(provider.providerType, provider.token, false); });
|
this._getOrCreateLocalProvider(provider.providerType, provider.token, false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get transformProviders(): ProviderAst[] { return this._transformedProviders.values(); }
|
get transformProviders(): ProviderAst[] { return this._transformedProviders.values(); }
|
||||||
|
@ -101,30 +115,42 @@ export class ProviderElementContext {
|
||||||
return sortedDirectives;
|
return sortedDirectives;
|
||||||
}
|
}
|
||||||
|
|
||||||
private isQueried(token: CompileTokenMetadata): boolean {
|
get transformedHasViewContainer(): boolean { return this._hasViewContainer; }
|
||||||
|
|
||||||
|
private _addQueryReadsTo(token: CompileTokenMetadata, queryReadTokens: CompileTokenMap<boolean>) {
|
||||||
|
this._getQueriesFor(token).forEach((query) => {
|
||||||
|
var queryReadToken = isPresent(query.read) ? query.read : token;
|
||||||
|
if (isBlank(queryReadTokens.get(queryReadToken))) {
|
||||||
|
queryReadTokens.add(queryReadToken, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getQueriesFor(token: CompileTokenMetadata): CompileQueryMetadata[] {
|
||||||
|
var result: CompileQueryMetadata[] = [];
|
||||||
var currentEl: ProviderElementContext = this;
|
var currentEl: ProviderElementContext = this;
|
||||||
var distance = 0;
|
var distance = 0;
|
||||||
|
var queries: CompileQueryMetadata[];
|
||||||
while (currentEl !== null) {
|
while (currentEl !== null) {
|
||||||
var localQueries = currentEl._contentQueries.get(token);
|
queries = currentEl._contentQueries.get(token);
|
||||||
if (isPresent(localQueries)) {
|
if (isPresent(queries)) {
|
||||||
if (localQueries.some((query) => query.descendants || distance <= 1)) {
|
ListWrapper.addAll(result, queries.filter((query) => query.descendants || distance <= 1));
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (currentEl._directiveAsts.length > 0) {
|
if (currentEl._directiveAsts.length > 0) {
|
||||||
distance++;
|
distance++;
|
||||||
}
|
}
|
||||||
currentEl = currentEl._parent;
|
currentEl = currentEl._parent;
|
||||||
}
|
}
|
||||||
if (isPresent(this._viewContext.viewQueries.get(token))) {
|
queries = this._viewContext.viewQueries.get(token);
|
||||||
return true;
|
if (isPresent(queries)) {
|
||||||
|
ListWrapper.addAll(result, queries);
|
||||||
}
|
}
|
||||||
return false;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private _getLocalProvider(requestingProviderType: ProviderAstType, token: CompileTokenMetadata,
|
private _getOrCreateLocalProvider(requestingProviderType: ProviderAstType,
|
||||||
eager: boolean): ProviderAst {
|
token: CompileTokenMetadata, eager: boolean): ProviderAst {
|
||||||
var resolvedProvider = this._allProviders.get(token);
|
var resolvedProvider = this._allProviders.get(token);
|
||||||
if (isBlank(resolvedProvider) ||
|
if (isBlank(resolvedProvider) ||
|
||||||
((requestingProviderType === ProviderAstType.Directive ||
|
((requestingProviderType === ProviderAstType.Directive ||
|
||||||
|
@ -198,17 +224,19 @@ export class ProviderElementContext {
|
||||||
if (dep.token.equalsTo(identifierToken(Identifiers.Renderer)) ||
|
if (dep.token.equalsTo(identifierToken(Identifiers.Renderer)) ||
|
||||||
dep.token.equalsTo(identifierToken(Identifiers.ElementRef)) ||
|
dep.token.equalsTo(identifierToken(Identifiers.ElementRef)) ||
|
||||||
dep.token.equalsTo(identifierToken(Identifiers.ChangeDetectorRef)) ||
|
dep.token.equalsTo(identifierToken(Identifiers.ChangeDetectorRef)) ||
|
||||||
dep.token.equalsTo(identifierToken(Identifiers.ViewContainerRef)) ||
|
|
||||||
dep.token.equalsTo(identifierToken(Identifiers.TemplateRef))) {
|
dep.token.equalsTo(identifierToken(Identifiers.TemplateRef))) {
|
||||||
return dep;
|
return dep;
|
||||||
}
|
}
|
||||||
|
if (dep.token.equalsTo(identifierToken(Identifiers.ViewContainerRef))) {
|
||||||
|
this._hasViewContainer = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// access the injector
|
// access the injector
|
||||||
if (dep.token.equalsTo(identifierToken(Identifiers.Injector))) {
|
if (dep.token.equalsTo(identifierToken(Identifiers.Injector))) {
|
||||||
return dep;
|
return dep;
|
||||||
}
|
}
|
||||||
// access providers
|
// access providers
|
||||||
if (isPresent(this._getLocalProvider(requestingProviderType, dep.token, eager))) {
|
if (isPresent(this._getOrCreateLocalProvider(requestingProviderType, dep.token, eager))) {
|
||||||
return dep;
|
return dep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -393,11 +421,11 @@ function _getContentQueries(
|
||||||
|
|
||||||
function _addQueryToTokenMap(map: CompileTokenMap<CompileQueryMetadata[]>,
|
function _addQueryToTokenMap(map: CompileTokenMap<CompileQueryMetadata[]>,
|
||||||
query: CompileQueryMetadata) {
|
query: CompileQueryMetadata) {
|
||||||
query.selectors.forEach((selector) => {
|
query.selectors.forEach((token: CompileTokenMetadata) => {
|
||||||
var entry = map.get(selector);
|
var entry = map.get(token);
|
||||||
if (isBlank(entry)) {
|
if (isBlank(entry)) {
|
||||||
entry = [];
|
entry = [];
|
||||||
map.add(selector, entry);
|
map.add(token, entry);
|
||||||
}
|
}
|
||||||
entry.push(query);
|
entry.push(query);
|
||||||
});
|
});
|
||||||
|
|
|
@ -225,8 +225,8 @@ class CompiledTemplate {
|
||||||
viewFactory: Function = null;
|
viewFactory: Function = null;
|
||||||
proxyViewFactory: Function;
|
proxyViewFactory: Function;
|
||||||
constructor() {
|
constructor() {
|
||||||
this.proxyViewFactory = (viewManager, childInjector, contextEl) =>
|
this.proxyViewFactory = (viewUtils, childInjector, contextEl) =>
|
||||||
this.viewFactory(viewManager, childInjector, contextEl);
|
this.viewFactory(viewUtils, childInjector, contextEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
init(viewFactory: Function) { this.viewFactory = viewFactory; }
|
init(viewFactory: Function) { this.viewFactory = viewFactory; }
|
||||||
|
|
|
@ -295,7 +295,8 @@ export class RuntimeMetadataResolver {
|
||||||
selectors: selectors,
|
selectors: selectors,
|
||||||
first: q.first,
|
first: q.first,
|
||||||
descendants: q.descendants,
|
descendants: q.descendants,
|
||||||
propertyName: propertyName
|
propertyName: propertyName,
|
||||||
|
read: isPresent(q.read) ? this.getTokenMetadata(q.read) : null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,8 +98,9 @@ export class ElementAst implements TemplateAst {
|
||||||
constructor(public name: string, public attrs: AttrAst[],
|
constructor(public name: string, public attrs: AttrAst[],
|
||||||
public inputs: BoundElementPropertyAst[], public outputs: BoundEventAst[],
|
public inputs: BoundElementPropertyAst[], public outputs: BoundEventAst[],
|
||||||
public exportAsVars: VariableAst[], public directives: DirectiveAst[],
|
public exportAsVars: VariableAst[], public directives: DirectiveAst[],
|
||||||
public providers: ProviderAst[], public children: TemplateAst[],
|
public providers: ProviderAst[], public hasViewContainer: boolean,
|
||||||
public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
|
public children: TemplateAst[], public ngContentIndex: number,
|
||||||
|
public sourceSpan: ParseSourceSpan) {}
|
||||||
|
|
||||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||||
return visitor.visitElement(this, context);
|
return visitor.visitElement(this, context);
|
||||||
|
@ -129,8 +130,8 @@ export class ElementAst implements TemplateAst {
|
||||||
export class EmbeddedTemplateAst implements TemplateAst {
|
export class EmbeddedTemplateAst implements TemplateAst {
|
||||||
constructor(public attrs: AttrAst[], public outputs: BoundEventAst[], public vars: VariableAst[],
|
constructor(public attrs: AttrAst[], public outputs: BoundEventAst[], public vars: VariableAst[],
|
||||||
public directives: DirectiveAst[], public providers: ProviderAst[],
|
public directives: DirectiveAst[], public providers: ProviderAst[],
|
||||||
public children: TemplateAst[], public ngContentIndex: number,
|
public hasViewContainer: boolean, public children: TemplateAst[],
|
||||||
public sourceSpan: ParseSourceSpan) {}
|
public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
|
||||||
|
|
||||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||||
return visitor.visitEmbeddedTemplate(this, context);
|
return visitor.visitEmbeddedTemplate(this, context);
|
||||||
|
|
|
@ -328,7 +328,7 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||||
var isViewRoot = parent.isTemplateElement || hasInlineTemplates;
|
var isViewRoot = parent.isTemplateElement || hasInlineTemplates;
|
||||||
var providerContext =
|
var providerContext =
|
||||||
new ProviderElementContext(this.providerViewContext, parent.providerContext, isViewRoot,
|
new ProviderElementContext(this.providerViewContext, parent.providerContext, isViewRoot,
|
||||||
directiveAsts, attrs, element.sourceSpan);
|
directiveAsts, attrs, vars, element.sourceSpan);
|
||||||
var children = htmlVisitAll(
|
var children = htmlVisitAll(
|
||||||
preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this, element.children,
|
preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this, element.children,
|
||||||
ElementContext.create(isTemplateElement, directiveAsts,
|
ElementContext.create(isTemplateElement, directiveAsts,
|
||||||
|
@ -355,10 +355,10 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||||
this._assertNoComponentsNorElementBindingsOnTemplate(directiveAsts, elementProps,
|
this._assertNoComponentsNorElementBindingsOnTemplate(directiveAsts, elementProps,
|
||||||
element.sourceSpan);
|
element.sourceSpan);
|
||||||
|
|
||||||
parsedElement =
|
parsedElement = new EmbeddedTemplateAst(
|
||||||
new EmbeddedTemplateAst(attrs, events, vars, providerContext.transformedDirectiveAsts,
|
attrs, events, vars, providerContext.transformedDirectiveAsts,
|
||||||
providerContext.transformProviders, children,
|
providerContext.transformProviders, providerContext.transformedHasViewContainer, children,
|
||||||
hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
|
hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
|
||||||
} else {
|
} else {
|
||||||
this._assertOnlyOneComponent(directiveAsts, element.sourceSpan);
|
this._assertOnlyOneComponent(directiveAsts, element.sourceSpan);
|
||||||
var elementExportAsVars = vars.filter(varAst => varAst.value.length === 0);
|
var elementExportAsVars = vars.filter(varAst => varAst.value.length === 0);
|
||||||
|
@ -367,7 +367,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||||
|
|
||||||
parsedElement = new ElementAst(
|
parsedElement = new ElementAst(
|
||||||
nodeName, attrs, elementProps, events, elementExportAsVars,
|
nodeName, attrs, elementProps, events, elementExportAsVars,
|
||||||
providerContext.transformedDirectiveAsts, providerContext.transformProviders, children,
|
providerContext.transformedDirectiveAsts, providerContext.transformProviders,
|
||||||
|
providerContext.transformedHasViewContainer, children,
|
||||||
hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
|
hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
|
||||||
}
|
}
|
||||||
if (hasInlineTemplates) {
|
if (hasInlineTemplates) {
|
||||||
|
@ -382,12 +383,13 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||||
templateDirectiveAsts, templateElementProps, element.sourceSpan);
|
templateDirectiveAsts, templateElementProps, element.sourceSpan);
|
||||||
var templateProviderContext = new ProviderElementContext(
|
var templateProviderContext = new ProviderElementContext(
|
||||||
this.providerViewContext, parent.providerContext, parent.isTemplateElement,
|
this.providerViewContext, parent.providerContext, parent.isTemplateElement,
|
||||||
templateDirectiveAsts, [], element.sourceSpan);
|
templateDirectiveAsts, [], templateVars, element.sourceSpan);
|
||||||
templateProviderContext.afterElement();
|
templateProviderContext.afterElement();
|
||||||
|
|
||||||
parsedElement = new EmbeddedTemplateAst([], [], templateVars,
|
parsedElement = new EmbeddedTemplateAst([], [], templateVars,
|
||||||
templateProviderContext.transformedDirectiveAsts,
|
templateProviderContext.transformedDirectiveAsts,
|
||||||
templateProviderContext.transformProviders,
|
templateProviderContext.transformProviders,
|
||||||
|
templateProviderContext.transformedHasViewContainer,
|
||||||
[parsedElement], ngContentIndex, element.sourceSpan);
|
[parsedElement], ngContentIndex, element.sourceSpan);
|
||||||
}
|
}
|
||||||
return parsedElement;
|
return parsedElement;
|
||||||
|
@ -765,8 +767,8 @@ class NonBindableVisitor implements HtmlAstVisitor {
|
||||||
var selector = createElementCssSelector(ast.name, attrNameAndValues);
|
var selector = createElementCssSelector(ast.name, attrNameAndValues);
|
||||||
var ngContentIndex = parent.findNgContentIndex(selector);
|
var ngContentIndex = parent.findNgContentIndex(selector);
|
||||||
var children = htmlVisitAll(this, ast.children, EMPTY_ELEMENT_CONTEXT);
|
var children = htmlVisitAll(this, ast.children, EMPTY_ELEMENT_CONTEXT);
|
||||||
return new ElementAst(ast.name, htmlVisitAll(this, ast.attrs), [], [], [], [], [], children,
|
return new ElementAst(ast.name, htmlVisitAll(this, ast.attrs), [], [], [], [], [], false,
|
||||||
ngContentIndex, ast.sourceSpan);
|
children, ngContentIndex, ast.sourceSpan);
|
||||||
}
|
}
|
||||||
visitComment(ast: HtmlCommentAst, context: any): any { return null; }
|
visitComment(ast: HtmlCommentAst, context: any): any { return null; }
|
||||||
visitAttr(ast: HtmlAttrAst, context: any): AttrAst {
|
visitAttr(ast: HtmlAttrAst, context: any): AttrAst {
|
||||||
|
|
|
@ -30,13 +30,13 @@ export class CompileNode {
|
||||||
|
|
||||||
export class CompileElement extends CompileNode {
|
export class CompileElement extends CompileNode {
|
||||||
static createNull(): CompileElement {
|
static createNull(): CompileElement {
|
||||||
return new CompileElement(null, null, null, null, null, [], [], {});
|
return new CompileElement(null, null, null, null, null, null, [], [], false, false, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _compViewExpr: o.Expression = null;
|
private _compViewExpr: o.Expression = null;
|
||||||
public component: CompileDirectiveMetadata = null;
|
public appElement: o.ReadPropExpr;
|
||||||
private _appElement: o.Expression;
|
public elementRef: o.Expression;
|
||||||
private _defaultInjector: o.Expression;
|
public injector: o.Expression;
|
||||||
private _instances = new CompileTokenMap<o.Expression>();
|
private _instances = new CompileTokenMap<o.Expression>();
|
||||||
private _resolvedProviders: CompileTokenMap<ProviderAst>;
|
private _resolvedProviders: CompileTokenMap<ProviderAst>;
|
||||||
|
|
||||||
|
@ -50,17 +50,45 @@ export class CompileElement extends CompileNode {
|
||||||
|
|
||||||
constructor(parent: CompileElement, view: CompileView, nodeIndex: number,
|
constructor(parent: CompileElement, view: CompileView, nodeIndex: number,
|
||||||
renderNode: o.Expression, sourceAst: TemplateAst,
|
renderNode: o.Expression, sourceAst: TemplateAst,
|
||||||
|
public component: CompileDirectiveMetadata,
|
||||||
private _directives: CompileDirectiveMetadata[],
|
private _directives: CompileDirectiveMetadata[],
|
||||||
private _resolvedProvidersArray: ProviderAst[],
|
private _resolvedProvidersArray: ProviderAst[], public hasViewContainer: boolean,
|
||||||
|
public hasEmbeddedView: boolean,
|
||||||
public variableTokens: {[key: string]: CompileTokenMetadata}) {
|
public variableTokens: {[key: string]: CompileTokenMetadata}) {
|
||||||
super(parent, view, nodeIndex, renderNode, sourceAst);
|
super(parent, view, nodeIndex, renderNode, sourceAst);
|
||||||
|
this.elementRef = o.importExpr(Identifiers.ElementRef).instantiate([this.renderNode]);
|
||||||
|
this._instances.add(identifierToken(Identifiers.ElementRef), this.elementRef);
|
||||||
|
this.injector = o.THIS_EXPR.callMethod('injector', [o.literal(this.nodeIndex)]);
|
||||||
|
this._instances.add(identifierToken(Identifiers.Injector), this.injector);
|
||||||
|
this._instances.add(identifierToken(Identifiers.Renderer), o.THIS_EXPR.prop('renderer'));
|
||||||
|
if (this.hasViewContainer || this.hasEmbeddedView || isPresent(this.component)) {
|
||||||
|
this._createAppElement();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setComponent(component: CompileDirectiveMetadata, compViewExpr: o.Expression) {
|
private _createAppElement() {
|
||||||
this.component = component;
|
var fieldName = `_appEl_${this.nodeIndex}`;
|
||||||
|
var parentNodeIndex = this.isRootElement() ? null : this.parent.nodeIndex;
|
||||||
|
this.view.fields.push(new o.ClassField(fieldName, o.importType(Identifiers.AppElement),
|
||||||
|
[o.StmtModifier.Private]));
|
||||||
|
var statement = o.THIS_EXPR.prop(fieldName)
|
||||||
|
.set(o.importExpr(Identifiers.AppElement)
|
||||||
|
.instantiate([
|
||||||
|
o.literal(this.nodeIndex),
|
||||||
|
o.literal(parentNodeIndex),
|
||||||
|
o.THIS_EXPR,
|
||||||
|
this.renderNode
|
||||||
|
]))
|
||||||
|
.toStmt();
|
||||||
|
this.view.createMethod.addStmt(statement);
|
||||||
|
this.appElement = o.THIS_EXPR.prop(fieldName);
|
||||||
|
this._instances.add(identifierToken(Identifiers.AppElement), this.appElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
setComponentView(compViewExpr: o.Expression) {
|
||||||
this._compViewExpr = compViewExpr;
|
this._compViewExpr = compViewExpr;
|
||||||
this.contentNodesByNgContentIndex =
|
this.contentNodesByNgContentIndex =
|
||||||
ListWrapper.createFixedSize(component.template.ngContentSelectors.length);
|
ListWrapper.createFixedSize(this.component.template.ngContentSelectors.length);
|
||||||
for (var i = 0; i < this.contentNodesByNgContentIndex.length; i++) {
|
for (var i = 0; i < this.contentNodesByNgContentIndex.length; i++) {
|
||||||
this.contentNodesByNgContentIndex[i] = [];
|
this.contentNodesByNgContentIndex[i] = [];
|
||||||
}
|
}
|
||||||
|
@ -71,7 +99,7 @@ export class CompileElement extends CompileNode {
|
||||||
if (isPresent(embeddedView)) {
|
if (isPresent(embeddedView)) {
|
||||||
var createTemplateRefExpr =
|
var createTemplateRefExpr =
|
||||||
o.importExpr(Identifiers.TemplateRef_)
|
o.importExpr(Identifiers.TemplateRef_)
|
||||||
.instantiate([this.getOrCreateAppElement(), this.embeddedView.viewFactory]);
|
.instantiate([this.appElement, this.embeddedView.viewFactory]);
|
||||||
var provider = new CompileProviderMetadata(
|
var provider = new CompileProviderMetadata(
|
||||||
{token: identifierToken(Identifiers.TemplateRef), useValue: createTemplateRefExpr});
|
{token: identifierToken(Identifiers.TemplateRef), useValue: createTemplateRefExpr});
|
||||||
// Add TemplateRef as first provider as it does not have deps on other providers
|
// Add TemplateRef as first provider as it does not have deps on other providers
|
||||||
|
@ -82,6 +110,11 @@ export class CompileElement extends CompileNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeChildren(): void {
|
beforeChildren(): void {
|
||||||
|
if (this.hasViewContainer) {
|
||||||
|
this._instances.add(identifierToken(Identifiers.ViewContainerRef),
|
||||||
|
this.appElement.prop('vcRef'));
|
||||||
|
}
|
||||||
|
|
||||||
this._resolvedProviders = new CompileTokenMap<ProviderAst>();
|
this._resolvedProviders = new CompileTokenMap<ProviderAst>();
|
||||||
this._resolvedProvidersArray.forEach(provider =>
|
this._resolvedProvidersArray.forEach(provider =>
|
||||||
this._resolvedProviders.add(provider.token, provider));
|
this._resolvedProviders.add(provider.token, provider));
|
||||||
|
@ -127,36 +160,54 @@ export class CompileElement extends CompileNode {
|
||||||
var directive = this._directives[i];
|
var directive = this._directives[i];
|
||||||
directive.queries.forEach((queryMeta) => { this._addQuery(queryMeta, directiveInstance); });
|
directive.queries.forEach((queryMeta) => { this._addQuery(queryMeta, directiveInstance); });
|
||||||
}
|
}
|
||||||
|
var queriesWithReads: _QueryWithRead[] = [];
|
||||||
this._resolvedProviders.values().forEach((resolvedProvider) => {
|
this._resolvedProviders.values().forEach((resolvedProvider) => {
|
||||||
var queriesForProvider = this._getQueriesFor(resolvedProvider.token);
|
var queriesForProvider = this._getQueriesFor(resolvedProvider.token);
|
||||||
var providerExpr = this._instances.get(resolvedProvider.token);
|
ListWrapper.addAll(
|
||||||
queriesForProvider.forEach((query) => { query.addValue(providerExpr, this.view); });
|
queriesWithReads,
|
||||||
|
queriesForProvider.map(query => new _QueryWithRead(query, resolvedProvider.token)));
|
||||||
});
|
});
|
||||||
StringMapWrapper.forEach(this.variableTokens, (_, varName) => {
|
StringMapWrapper.forEach(this.variableTokens, (_, varName) => {
|
||||||
var token = this.variableTokens[varName];
|
var token = this.variableTokens[varName];
|
||||||
var varValue;
|
var varValue;
|
||||||
var varValueForQuery;
|
|
||||||
if (isPresent(token)) {
|
if (isPresent(token)) {
|
||||||
varValue = varValueForQuery = this._instances.get(token);
|
varValue = this._instances.get(token);
|
||||||
} else {
|
} else {
|
||||||
varValueForQuery = this.getOrCreateAppElement().prop('ref');
|
|
||||||
varValue = this.renderNode;
|
varValue = this.renderNode;
|
||||||
}
|
}
|
||||||
this.view.variables.set(varName, varValue);
|
this.view.variables.set(varName, varValue);
|
||||||
this.view.namedAppElements.push([varName, this.getOrCreateAppElement()]);
|
var varToken = new CompileTokenMetadata({value: varName});
|
||||||
|
ListWrapper.addAll(queriesWithReads, this._getQueriesFor(varToken)
|
||||||
var queriesForProvider = this._getQueriesFor(new CompileTokenMetadata({value: varName}));
|
.map(query => new _QueryWithRead(query, varToken)));
|
||||||
queriesForProvider.forEach((query) => { query.addValue(varValueForQuery, this.view); });
|
|
||||||
});
|
});
|
||||||
|
queriesWithReads.forEach((queryWithRead) => {
|
||||||
|
var value: o.Expression;
|
||||||
|
if (isPresent(queryWithRead.read.identifier)) {
|
||||||
|
// query for an identifier
|
||||||
|
value = this._instances.get(queryWithRead.read);
|
||||||
|
} else {
|
||||||
|
// query for a variable
|
||||||
|
var token = this.variableTokens[queryWithRead.read.value];
|
||||||
|
if (isPresent(token)) {
|
||||||
|
value = this._instances.get(token);
|
||||||
|
} else {
|
||||||
|
value = this.elementRef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isPresent(value)) {
|
||||||
|
queryWithRead.query.addValue(value, this.view);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (isPresent(this.component)) {
|
if (isPresent(this.component)) {
|
||||||
var componentConstructorViewQueryList =
|
var componentConstructorViewQueryList =
|
||||||
isPresent(this.component) ? o.literalArr(this._componentConstructorViewQueryLists) :
|
isPresent(this.component) ? o.literalArr(this._componentConstructorViewQueryLists) :
|
||||||
o.NULL_EXPR;
|
o.NULL_EXPR;
|
||||||
var compExpr = isPresent(this.getComponent()) ? this.getComponent() : o.NULL_EXPR;
|
var compExpr = isPresent(this.getComponent()) ? this.getComponent() : o.NULL_EXPR;
|
||||||
this.view.createMethod.addStmt(
|
this.view.createMethod.addStmt(
|
||||||
this.getOrCreateAppElement()
|
this.appElement.callMethod(
|
||||||
.callMethod('initComponent',
|
'initComponent',
|
||||||
[compExpr, componentConstructorViewQueryList, this._compViewExpr])
|
[compExpr, componentConstructorViewQueryList, this._compViewExpr])
|
||||||
.toStmt());
|
.toStmt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,43 +253,6 @@ export class CompileElement extends CompileNode {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
getOptionalAppElement(): o.Expression { return this._appElement; }
|
|
||||||
|
|
||||||
getOrCreateAppElement(): o.Expression {
|
|
||||||
if (isBlank(this._appElement)) {
|
|
||||||
var parentNodeIndex = this.isRootElement() ? null : this.parent.nodeIndex;
|
|
||||||
var fieldName = `_appEl_${this.nodeIndex}`;
|
|
||||||
this.view.fields.push(new o.ClassField(fieldName, o.importType(Identifiers.AppElement),
|
|
||||||
[o.StmtModifier.Private]));
|
|
||||||
var statement = o.THIS_EXPR.prop(fieldName)
|
|
||||||
.set(o.importExpr(Identifiers.AppElement)
|
|
||||||
.instantiate([
|
|
||||||
o.literal(this.nodeIndex),
|
|
||||||
o.literal(parentNodeIndex),
|
|
||||||
o.THIS_EXPR,
|
|
||||||
this.renderNode
|
|
||||||
]))
|
|
||||||
.toStmt();
|
|
||||||
this.view.createMethod.addStmt(statement);
|
|
||||||
this._appElement = o.THIS_EXPR.prop(fieldName);
|
|
||||||
}
|
|
||||||
return this._appElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
getOrCreateInjector(): o.Expression {
|
|
||||||
if (isBlank(this._defaultInjector)) {
|
|
||||||
var fieldName = `_inj_${this.nodeIndex}`;
|
|
||||||
this.view.fields.push(new o.ClassField(fieldName, o.importType(Identifiers.Injector),
|
|
||||||
[o.StmtModifier.Private]));
|
|
||||||
var statement = o.THIS_EXPR.prop(fieldName)
|
|
||||||
.set(o.THIS_EXPR.callMethod('injector', [o.literal(this.nodeIndex)]))
|
|
||||||
.toStmt();
|
|
||||||
this.view.createMethod.addStmt(statement);
|
|
||||||
this._defaultInjector = o.THIS_EXPR.prop(fieldName);
|
|
||||||
}
|
|
||||||
return this._defaultInjector;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _getQueriesFor(token: CompileTokenMetadata): CompileQuery[] {
|
private _getQueriesFor(token: CompileTokenMetadata): CompileQuery[] {
|
||||||
var result: CompileQuery[] = [];
|
var result: CompileQuery[] = [];
|
||||||
var currentEl: CompileElement = this;
|
var currentEl: CompileElement = this;
|
||||||
|
@ -289,30 +303,20 @@ export class CompileElement extends CompileNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPresent(dep.token)) {
|
if (isPresent(dep.token)) {
|
||||||
// access builtins
|
// access builtins with special visibility
|
||||||
if (isBlank(result)) {
|
if (isBlank(result)) {
|
||||||
if (dep.token.equalsTo(identifierToken(Identifiers.Renderer))) {
|
if (dep.token.equalsTo(identifierToken(Identifiers.ChangeDetectorRef))) {
|
||||||
result = o.THIS_EXPR.prop('renderer');
|
|
||||||
} else if (dep.token.equalsTo(identifierToken(Identifiers.ElementRef))) {
|
|
||||||
result = this.getOrCreateAppElement().prop('ref');
|
|
||||||
} else if (dep.token.equalsTo(identifierToken(Identifiers.ChangeDetectorRef))) {
|
|
||||||
if (requestingProviderType === ProviderAstType.Component) {
|
if (requestingProviderType === ProviderAstType.Component) {
|
||||||
return this._compViewExpr.prop('ref');
|
return this._compViewExpr.prop('ref');
|
||||||
} else {
|
} else {
|
||||||
return o.THIS_EXPR.prop('ref');
|
return o.THIS_EXPR.prop('ref');
|
||||||
}
|
}
|
||||||
} else if (dep.token.equalsTo(identifierToken(Identifiers.ViewContainerRef))) {
|
|
||||||
result = this.getOrCreateAppElement().prop('vcRef');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// access providers
|
// access regular providers on the element
|
||||||
if (isBlank(result)) {
|
if (isBlank(result)) {
|
||||||
result = this._instances.get(dep.token);
|
result = this._instances.get(dep.token);
|
||||||
}
|
}
|
||||||
// access the injector
|
|
||||||
if (isBlank(result) && dep.token.equalsTo(identifierToken(Identifiers.Injector))) {
|
|
||||||
result = this.getOrCreateInjector();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -400,3 +404,10 @@ function createProviderProperty(propName: string, provider: ProviderAst,
|
||||||
}
|
}
|
||||||
return o.THIS_EXPR.prop(propName);
|
return o.THIS_EXPR.prop(propName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _QueryWithRead {
|
||||||
|
public read: CompileTokenMetadata;
|
||||||
|
constructor(public query: CompileQuery, match: CompileTokenMetadata) {
|
||||||
|
this.read = isPresent(query.meta.read) ? query.meta.read : match;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ export class CompileQuery {
|
||||||
function createQueryValues(viewValues: ViewQueryValues): o.Expression[] {
|
function createQueryValues(viewValues: ViewQueryValues): o.Expression[] {
|
||||||
return ListWrapper.flatten(viewValues.values.map((entry) => {
|
return ListWrapper.flatten(viewValues.values.map((entry) => {
|
||||||
if (entry instanceof ViewQueryValues) {
|
if (entry instanceof ViewQueryValues) {
|
||||||
return mapNestedViews(entry.view.declarationElement.getOrCreateAppElement(), entry.view,
|
return mapNestedViews(entry.view.declarationElement.appElement, entry.view,
|
||||||
createQueryValues(entry));
|
createQueryValues(entry));
|
||||||
} else {
|
} else {
|
||||||
return <o.Expression>entry;
|
return <o.Expression>entry;
|
||||||
|
|
|
@ -33,9 +33,9 @@ export class CompilePipe {
|
||||||
export class CompileView implements NameResolver {
|
export class CompileView implements NameResolver {
|
||||||
public viewType: ViewType;
|
public viewType: ViewType;
|
||||||
public viewQueries: CompileTokenMap<CompileQuery[]>;
|
public viewQueries: CompileTokenMap<CompileQuery[]>;
|
||||||
public namedAppElements: Array<Array<string | o.Expression>> = [];
|
|
||||||
|
|
||||||
public nodes: CompileNode[] = [];
|
public nodes: CompileNode[] = [];
|
||||||
|
// root nodes or AppElements for ViewContainers
|
||||||
public rootNodesOrAppElements: o.Expression[] = [];
|
public rootNodesOrAppElements: o.Expression[] = [];
|
||||||
|
|
||||||
public bindings: CompileBinding[] = [];
|
public bindings: CompileBinding[] = [];
|
||||||
|
|
|
@ -59,7 +59,7 @@ export class ChangeDetectionStrategyEnum {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ViewConstructorVars {
|
export class ViewConstructorVars {
|
||||||
static viewManager = o.variable('viewManager');
|
static viewUtils = o.variable('viewUtils');
|
||||||
static parentInjector = o.variable('parentInjector');
|
static parentInjector = o.variable('parentInjector');
|
||||||
static declarationEl = o.variable('declarationEl');
|
static declarationEl = o.variable('declarationEl');
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ export class ViewConstructorVars {
|
||||||
export class ViewProperties {
|
export class ViewProperties {
|
||||||
static renderer = o.THIS_EXPR.prop('renderer');
|
static renderer = o.THIS_EXPR.prop('renderer');
|
||||||
static projectableNodes = o.THIS_EXPR.prop('projectableNodes');
|
static projectableNodes = o.THIS_EXPR.prop('projectableNodes');
|
||||||
static viewManager = o.THIS_EXPR.prop('viewManager');
|
static viewUtils = o.THIS_EXPR.prop('viewUtils');
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EventHandlerVars { static event = o.variable('$event'); }
|
export class EventHandlerVars { static event = o.variable('$event'); }
|
||||||
|
|
|
@ -67,10 +67,9 @@ export class CompileEventListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
finishMethod() {
|
finishMethod() {
|
||||||
var markPathToRootStart =
|
var markPathToRootStart = this._hasComponentHostListener ?
|
||||||
this._hasComponentHostListener ?
|
this.compileElement.appElement.prop('componentView') :
|
||||||
this.compileElement.getOrCreateAppElement().prop('componentView') :
|
o.THIS_EXPR;
|
||||||
o.THIS_EXPR;
|
|
||||||
var resultExpr: o.Expression = o.literal(true);
|
var resultExpr: o.Expression = o.literal(true);
|
||||||
this._actionResultExprs.forEach((expr) => { resultExpr = resultExpr.and(expr); });
|
this._actionResultExprs.forEach((expr) => { resultExpr = resultExpr.and(expr); });
|
||||||
var stmts =
|
var stmts =
|
||||||
|
|
|
@ -189,8 +189,7 @@ export function bindDirectiveInputs(directiveAst: DirectiveAst, directiveInstanc
|
||||||
});
|
});
|
||||||
if (isOnPushComp) {
|
if (isOnPushComp) {
|
||||||
detectChangesInInputsMethod.addStmt(new o.IfStmt(DetectChangesVars.changed, [
|
detectChangesInInputsMethod.addStmt(new o.IfStmt(DetectChangesVars.changed, [
|
||||||
compileElement.getOrCreateAppElement()
|
compileElement.appElement.prop('componentView')
|
||||||
.prop('componentView')
|
|
||||||
.callMethod('markAsCheckOnce', [])
|
.callMethod('markAsCheckOnce', [])
|
||||||
.toStmt()
|
.toStmt()
|
||||||
]));
|
]));
|
||||||
|
|
|
@ -92,14 +92,15 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
|
||||||
|
|
||||||
private _addRootNodeAndProject(node: CompileNode, ngContentIndex: number,
|
private _addRootNodeAndProject(node: CompileNode, ngContentIndex: number,
|
||||||
parent: CompileElement) {
|
parent: CompileElement) {
|
||||||
var appEl = node instanceof CompileElement ? node.getOptionalAppElement() : null;
|
var vcAppEl =
|
||||||
|
(node instanceof CompileElement && node.hasViewContainer) ? node.appElement : null;
|
||||||
if (this._isRootNode(parent)) {
|
if (this._isRootNode(parent)) {
|
||||||
// store root nodes only for embedded/host views
|
// store appElement as root node only for ViewContainers
|
||||||
if (this.view.viewType !== ViewType.COMPONENT) {
|
if (this.view.viewType !== ViewType.COMPONENT) {
|
||||||
this.view.rootNodesOrAppElements.push(isPresent(appEl) ? appEl : node.renderNode);
|
this.view.rootNodesOrAppElements.push(isPresent(vcAppEl) ? vcAppEl : node.renderNode);
|
||||||
}
|
}
|
||||||
} else if (isPresent(parent.component) && isPresent(ngContentIndex)) {
|
} else if (isPresent(parent.component) && isPresent(ngContentIndex)) {
|
||||||
parent.addContentNode(ngContentIndex, isPresent(appEl) ? appEl : node.renderNode);
|
parent.addContentNode(ngContentIndex, isPresent(vcAppEl) ? vcAppEl : node.renderNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +197,7 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
|
||||||
this.view.fields.push(
|
this.view.fields.push(
|
||||||
new o.ClassField(fieldName, o.importType(this.view.genConfig.renderTypes.renderElement),
|
new o.ClassField(fieldName, o.importType(this.view.genConfig.renderTypes.renderElement),
|
||||||
[o.StmtModifier.Private]));
|
[o.StmtModifier.Private]));
|
||||||
var createRenderNode = o.THIS_EXPR.prop(fieldName).set(createRenderNodeExpr).toStmt();
|
this.view.createMethod.addStmt(o.THIS_EXPR.prop(fieldName).set(createRenderNodeExpr).toStmt());
|
||||||
|
|
||||||
var renderNode = o.THIS_EXPR.prop(fieldName);
|
var renderNode = o.THIS_EXPR.prop(fieldName);
|
||||||
|
|
||||||
|
@ -204,7 +205,6 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
|
||||||
var directives = ast.directives.map(directiveAst => directiveAst.directive);
|
var directives = ast.directives.map(directiveAst => directiveAst.directive);
|
||||||
var variables =
|
var variables =
|
||||||
_readHtmlAndDirectiveVariables(ast.exportAsVars, ast.directives, this.view.viewType);
|
_readHtmlAndDirectiveVariables(ast.exportAsVars, ast.directives, this.view.viewType);
|
||||||
this.view.createMethod.addStmt(createRenderNode);
|
|
||||||
var htmlAttrs = _readHtmlAttrs(ast.attrs);
|
var htmlAttrs = _readHtmlAttrs(ast.attrs);
|
||||||
var attrNameAndValues = _mergeHtmlAndDirectiveAttrs(htmlAttrs, directives);
|
var attrNameAndValues = _mergeHtmlAndDirectiveAttrs(htmlAttrs, directives);
|
||||||
for (var i = 0; i < attrNameAndValues.length; i++) {
|
for (var i = 0; i < attrNameAndValues.length; i++) {
|
||||||
|
@ -216,8 +216,9 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
|
||||||
[renderNode, o.literal(attrName), o.literal(attrValue)])
|
[renderNode, o.literal(attrName), o.literal(attrValue)])
|
||||||
.toStmt());
|
.toStmt());
|
||||||
}
|
}
|
||||||
var compileElement = new CompileElement(parent, this.view, nodeIndex, renderNode, ast,
|
var compileElement =
|
||||||
directives, ast.providers, variables);
|
new CompileElement(parent, this.view, nodeIndex, renderNode, ast, component, directives,
|
||||||
|
ast.providers, ast.hasViewContainer, false, variables);
|
||||||
this.view.nodes.push(compileElement);
|
this.view.nodes.push(compileElement);
|
||||||
var compViewExpr: o.ReadVarExpr = null;
|
var compViewExpr: o.ReadVarExpr = null;
|
||||||
if (isPresent(component)) {
|
if (isPresent(component)) {
|
||||||
|
@ -225,14 +226,14 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
|
||||||
new CompileIdentifierMetadata({name: getViewFactoryName(component, 0)});
|
new CompileIdentifierMetadata({name: getViewFactoryName(component, 0)});
|
||||||
this.targetDependencies.push(new ViewCompileDependency(component, nestedComponentIdentifier));
|
this.targetDependencies.push(new ViewCompileDependency(component, nestedComponentIdentifier));
|
||||||
compViewExpr = o.variable(`compView_${nodeIndex}`);
|
compViewExpr = o.variable(`compView_${nodeIndex}`);
|
||||||
|
compileElement.setComponentView(compViewExpr);
|
||||||
this.view.createMethod.addStmt(compViewExpr.set(o.importExpr(nestedComponentIdentifier)
|
this.view.createMethod.addStmt(compViewExpr.set(o.importExpr(nestedComponentIdentifier)
|
||||||
.callFn([
|
.callFn([
|
||||||
ViewProperties.viewManager,
|
ViewProperties.viewUtils,
|
||||||
compileElement.getOrCreateInjector(),
|
compileElement.injector,
|
||||||
compileElement.getOrCreateAppElement()
|
compileElement.appElement
|
||||||
]))
|
]))
|
||||||
.toDeclStmt());
|
.toDeclStmt());
|
||||||
compileElement.setComponent(component, compViewExpr);
|
|
||||||
}
|
}
|
||||||
compileElement.beforeChildren();
|
compileElement.beforeChildren();
|
||||||
this._addRootNodeAndProject(compileElement, ast.ngContentIndex, parent);
|
this._addRootNodeAndProject(compileElement, ast.ngContentIndex, parent);
|
||||||
|
@ -259,24 +260,25 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
|
||||||
this.view.fields.push(
|
this.view.fields.push(
|
||||||
new o.ClassField(fieldName, o.importType(this.view.genConfig.renderTypes.renderComment),
|
new o.ClassField(fieldName, o.importType(this.view.genConfig.renderTypes.renderComment),
|
||||||
[o.StmtModifier.Private]));
|
[o.StmtModifier.Private]));
|
||||||
var createRenderNode = o.THIS_EXPR.prop(fieldName)
|
this.view.createMethod.addStmt(
|
||||||
.set(ViewProperties.renderer.callMethod(
|
o.THIS_EXPR.prop(fieldName)
|
||||||
'createTemplateAnchor',
|
.set(ViewProperties.renderer.callMethod(
|
||||||
[
|
'createTemplateAnchor',
|
||||||
this._getParentRenderNode(parent),
|
[
|
||||||
this.view.createMethod.resetDebugInfoExpr(nodeIndex, ast)
|
this._getParentRenderNode(parent),
|
||||||
]))
|
this.view.createMethod.resetDebugInfoExpr(nodeIndex, ast)
|
||||||
.toStmt();
|
]))
|
||||||
|
.toStmt());
|
||||||
var renderNode = o.THIS_EXPR.prop(fieldName);
|
var renderNode = o.THIS_EXPR.prop(fieldName);
|
||||||
|
|
||||||
var templateVariableBindings = ast.vars.map(
|
var templateVariableBindings = ast.vars.map(
|
||||||
varAst => [varAst.value.length > 0 ? varAst.value : IMPLICIT_TEMPLATE_VAR, varAst.name]);
|
varAst => [varAst.value.length > 0 ? varAst.value : IMPLICIT_TEMPLATE_VAR, varAst.name]);
|
||||||
|
|
||||||
var directives = ast.directives.map(directiveAst => directiveAst.directive);
|
var directives = ast.directives.map(directiveAst => directiveAst.directive);
|
||||||
var compileElement = new CompileElement(parent, this.view, nodeIndex, renderNode, ast,
|
var compileElement =
|
||||||
directives, ast.providers, {});
|
new CompileElement(parent, this.view, nodeIndex, renderNode, ast, null, directives,
|
||||||
|
ast.providers, ast.hasViewContainer, true, {});
|
||||||
this.view.nodes.push(compileElement);
|
this.view.nodes.push(compileElement);
|
||||||
this.view.createMethod.addStmt(createRenderNode);
|
|
||||||
|
|
||||||
this.nestedViewCount++;
|
this.nestedViewCount++;
|
||||||
var embeddedView = new CompileView(
|
var embeddedView = new CompileView(
|
||||||
|
@ -413,7 +415,7 @@ function createViewClass(view: CompileView, renderCompTypeVar: o.ReadVarExpr,
|
||||||
var emptyTemplateVariableBindings =
|
var emptyTemplateVariableBindings =
|
||||||
view.templateVariableBindings.map((entry) => [entry[0], o.NULL_EXPR]);
|
view.templateVariableBindings.map((entry) => [entry[0], o.NULL_EXPR]);
|
||||||
var viewConstructorArgs = [
|
var viewConstructorArgs = [
|
||||||
new o.FnParam(ViewConstructorVars.viewManager.name, o.importType(Identifiers.AppViewManager_)),
|
new o.FnParam(ViewConstructorVars.viewUtils.name, o.importType(Identifiers.ViewUtils)),
|
||||||
new o.FnParam(ViewConstructorVars.parentInjector.name, o.importType(Identifiers.Injector)),
|
new o.FnParam(ViewConstructorVars.parentInjector.name, o.importType(Identifiers.Injector)),
|
||||||
new o.FnParam(ViewConstructorVars.declarationEl.name, o.importType(Identifiers.AppElement))
|
new o.FnParam(ViewConstructorVars.declarationEl.name, o.importType(Identifiers.AppElement))
|
||||||
];
|
];
|
||||||
|
@ -423,7 +425,7 @@ function createViewClass(view: CompileView, renderCompTypeVar: o.ReadVarExpr,
|
||||||
renderCompTypeVar,
|
renderCompTypeVar,
|
||||||
ViewTypeEnum.fromValue(view.viewType),
|
ViewTypeEnum.fromValue(view.viewType),
|
||||||
o.literalMap(emptyTemplateVariableBindings),
|
o.literalMap(emptyTemplateVariableBindings),
|
||||||
ViewConstructorVars.viewManager,
|
ViewConstructorVars.viewUtils,
|
||||||
ViewConstructorVars.parentInjector,
|
ViewConstructorVars.parentInjector,
|
||||||
ViewConstructorVars.declarationEl,
|
ViewConstructorVars.declarationEl,
|
||||||
ChangeDetectionStrategyEnum.fromValue(getChangeDetectionMode(view)),
|
ChangeDetectionStrategyEnum.fromValue(getChangeDetectionMode(view)),
|
||||||
|
@ -462,7 +464,7 @@ function createViewClass(view: CompileView, renderCompTypeVar: o.ReadVarExpr,
|
||||||
function createViewFactory(view: CompileView, viewClass: o.ClassStmt,
|
function createViewFactory(view: CompileView, viewClass: o.ClassStmt,
|
||||||
renderCompTypeVar: o.ReadVarExpr): o.Statement {
|
renderCompTypeVar: o.ReadVarExpr): o.Statement {
|
||||||
var viewFactoryArgs = [
|
var viewFactoryArgs = [
|
||||||
new o.FnParam(ViewConstructorVars.viewManager.name, o.importType(Identifiers.AppViewManager_)),
|
new o.FnParam(ViewConstructorVars.viewUtils.name, o.importType(Identifiers.ViewUtils)),
|
||||||
new o.FnParam(ViewConstructorVars.parentInjector.name, o.importType(Identifiers.Injector)),
|
new o.FnParam(ViewConstructorVars.parentInjector.name, o.importType(Identifiers.Injector)),
|
||||||
new o.FnParam(ViewConstructorVars.declarationEl.name, o.importType(Identifiers.AppElement))
|
new o.FnParam(ViewConstructorVars.declarationEl.name, o.importType(Identifiers.AppElement))
|
||||||
];
|
];
|
||||||
|
@ -478,15 +480,16 @@ function createViewFactory(view: CompileView, viewClass: o.ClassStmt,
|
||||||
initRenderCompTypeStmts = [
|
initRenderCompTypeStmts = [
|
||||||
new o.IfStmt(renderCompTypeVar.identical(o.NULL_EXPR),
|
new o.IfStmt(renderCompTypeVar.identical(o.NULL_EXPR),
|
||||||
[
|
[
|
||||||
renderCompTypeVar.set(ViewConstructorVars.viewManager
|
renderCompTypeVar.set(ViewConstructorVars
|
||||||
.callMethod('createRenderComponentType',
|
.viewUtils.callMethod('createRenderComponentType',
|
||||||
[
|
[
|
||||||
o.literal(templateUrlInfo),
|
o.literal(templateUrlInfo),
|
||||||
o.literal(
|
o.literal(view.component
|
||||||
view.component.template.ngContentSelectors.length),
|
.template.ngContentSelectors.length),
|
||||||
ViewEncapsulationEnum.fromValue(view.component.template.encapsulation),
|
ViewEncapsulationEnum
|
||||||
view.styles
|
.fromValue(view.component.template.encapsulation),
|
||||||
]))
|
view.styles
|
||||||
|
]))
|
||||||
.toStmt()
|
.toStmt()
|
||||||
])
|
])
|
||||||
];
|
];
|
||||||
|
@ -513,7 +516,7 @@ function generateCreateMethod(view: CompileView): o.Statement[] {
|
||||||
}
|
}
|
||||||
var resultExpr: o.Expression;
|
var resultExpr: o.Expression;
|
||||||
if (view.viewType === ViewType.HOST) {
|
if (view.viewType === ViewType.HOST) {
|
||||||
resultExpr = (<CompileElement>view.nodes[0]).getOrCreateAppElement();
|
resultExpr = (<CompileElement>view.nodes[0]).appElement;
|
||||||
} else {
|
} else {
|
||||||
resultExpr = o.NULL_EXPR;
|
resultExpr = o.NULL_EXPR;
|
||||||
}
|
}
|
||||||
|
@ -523,7 +526,6 @@ function generateCreateMethod(view: CompileView): o.Statement[] {
|
||||||
[
|
[
|
||||||
createFlatArray(view.rootNodesOrAppElements),
|
createFlatArray(view.rootNodesOrAppElements),
|
||||||
o.literalArr(view.nodes.map(node => node.renderNode)),
|
o.literalArr(view.nodes.map(node => node.renderNode)),
|
||||||
o.literalMap(view.namedAppElements),
|
|
||||||
o.literalArr(view.disposables),
|
o.literalArr(view.disposables),
|
||||||
o.literalArr(view.subscriptions)
|
o.literalArr(view.subscriptions)
|
||||||
])
|
])
|
||||||
|
|
|
@ -11,8 +11,7 @@ import {
|
||||||
KeyValueDiffers,
|
KeyValueDiffers,
|
||||||
defaultKeyValueDiffers
|
defaultKeyValueDiffers
|
||||||
} from './change_detection/change_detection';
|
} from './change_detection/change_detection';
|
||||||
import {AppViewManager} from './linker/view_manager';
|
import {ViewUtils} from "./linker/view_utils";
|
||||||
import {AppViewManager_} from "./linker/view_manager";
|
|
||||||
import {ComponentResolver} from './linker/component_resolver';
|
import {ComponentResolver} from './linker/component_resolver';
|
||||||
import {ReflectorComponentResolver} from "./linker/component_resolver";
|
import {ReflectorComponentResolver} from "./linker/component_resolver";
|
||||||
import {DynamicComponentLoader} from './linker/dynamic_component_loader';
|
import {DynamicComponentLoader} from './linker/dynamic_component_loader';
|
||||||
|
@ -27,7 +26,7 @@ var __unused: Type; // avoid unused import when Type union types are erased
|
||||||
export const APPLICATION_COMMON_PROVIDERS: Array<Type | Provider | any[]> = CONST_EXPR([
|
export const APPLICATION_COMMON_PROVIDERS: Array<Type | Provider | any[]> = CONST_EXPR([
|
||||||
new Provider(ComponentResolver, {useClass: ReflectorComponentResolver}),
|
new Provider(ComponentResolver, {useClass: ReflectorComponentResolver}),
|
||||||
APP_ID_RANDOM_PROVIDER,
|
APP_ID_RANDOM_PROVIDER,
|
||||||
new Provider(AppViewManager, {useClass: AppViewManager_}),
|
ViewUtils,
|
||||||
new Provider(IterableDiffers, {useValue: defaultIterableDiffers}),
|
new Provider(IterableDiffers, {useValue: defaultIterableDiffers}),
|
||||||
new Provider(KeyValueDiffers, {useValue: defaultKeyValueDiffers}),
|
new Provider(KeyValueDiffers, {useValue: defaultKeyValueDiffers}),
|
||||||
new Provider(DynamicComponentLoader, {useClass: DynamicComponentLoader_})
|
new Provider(DynamicComponentLoader, {useClass: DynamicComponentLoader_})
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// Public API for compiler
|
// Public API for compiler
|
||||||
export {ComponentResolver} from './linker/component_resolver';
|
export {ComponentResolver} from './linker/component_resolver';
|
||||||
export {AppViewManager} from './linker/view_manager';
|
|
||||||
export {QueryList} from './linker/query_list';
|
export {QueryList} from './linker/query_list';
|
||||||
export {DynamicComponentLoader} from './linker/dynamic_component_loader';
|
export {DynamicComponentLoader} from './linker/dynamic_component_loader';
|
||||||
export {ElementRef} from './linker/element_ref';
|
export {ElementRef} from './linker/element_ref';
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import {Injector} from 'angular2/src/core/di';
|
import {Injector} from 'angular2/src/core/di';
|
||||||
import {Type, CONST, isPresent, isBlank} from 'angular2/src/facade/lang';
|
import {Type, CONST, isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||||
import {unimplemented} from 'angular2/src/facade/exceptions';
|
import {unimplemented} from 'angular2/src/facade/exceptions';
|
||||||
import {ElementRef, ElementRef_} from './element_ref';
|
import {ElementRef} from './element_ref';
|
||||||
import {ViewRef, ViewRef_} from './view_ref';
|
import {ViewRef, ViewRef_} from './view_ref';
|
||||||
import {AppElement} from './element';
|
import {AppElement} from './element';
|
||||||
import {AppViewManager} from './view_manager';
|
import {ViewUtils} from './view_utils';
|
||||||
import {ChangeDetectorRef} from '../change_detection/change_detection';
|
import {ChangeDetectorRef} from '../change_detection/change_detection';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,7 +38,7 @@ export abstract class ComponentRef {
|
||||||
/**
|
/**
|
||||||
* The {@link ChangeDetectorRef} of the Component instance.
|
* The {@link ChangeDetectorRef} of the Component instance.
|
||||||
*/
|
*/
|
||||||
get changeDetectorRef(): ChangeDetectorRef { return unimplemented(); };
|
get changeDetectorRef(): ChangeDetectorRef { return unimplemented(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The component type.
|
* The component type.
|
||||||
|
@ -57,15 +57,15 @@ export abstract class ComponentRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ComponentRef_ extends ComponentRef {
|
export class ComponentRef_ extends ComponentRef {
|
||||||
constructor(private _location: AppElement, private _componentType: Type) { super(); }
|
constructor(private _hostElement: AppElement, private _componentType: Type) { super(); }
|
||||||
get location(): ElementRef { return this._location.ref; }
|
get location(): ElementRef { return this._hostElement.elementRef; }
|
||||||
get injector(): Injector { return this._location.injector; }
|
get injector(): Injector { return this._hostElement.injector; }
|
||||||
get instance(): any { return this._location.component; };
|
get instance(): any { return this._hostElement.component; };
|
||||||
get hostView(): ViewRef { return this._location.parentView.ref; };
|
get hostView(): ViewRef { return this._hostElement.parentView.ref; };
|
||||||
get changeDetectorRef(): ChangeDetectorRef { return this.hostView; };
|
get changeDetectorRef(): ChangeDetectorRef { return this.hostView; };
|
||||||
get componentType(): Type { return this._componentType; }
|
get componentType(): Type { return this._componentType; }
|
||||||
|
|
||||||
destroy(): void { this._location.parentView.destroy(); }
|
destroy(): void { this._hostElement.parentView.destroy(); }
|
||||||
onDestroy(callback: Function): void { this.hostView.onDestroy(callback); }
|
onDestroy(callback: Function): void { this.hostView.onDestroy(callback); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,12 +81,12 @@ export class ComponentFactory {
|
||||||
*/
|
*/
|
||||||
create(injector: Injector, projectableNodes: any[][] = null,
|
create(injector: Injector, projectableNodes: any[][] = null,
|
||||||
rootSelectorOrNode: string | any = null): ComponentRef {
|
rootSelectorOrNode: string | any = null): ComponentRef {
|
||||||
var vm: AppViewManager = injector.get(AppViewManager);
|
var vu: ViewUtils = injector.get(ViewUtils);
|
||||||
if (isBlank(projectableNodes)) {
|
if (isBlank(projectableNodes)) {
|
||||||
projectableNodes = [];
|
projectableNodes = [];
|
||||||
}
|
}
|
||||||
// Note: Host views don't need a declarationAppElement!
|
// Note: Host views don't need a declarationAppElement!
|
||||||
var hostView = this._viewFactory(vm, injector, null);
|
var hostView = this._viewFactory(vu, injector, null);
|
||||||
var hostElement = hostView.create(projectableNodes, rootSelectorOrNode);
|
var hostElement = hostView.create(projectableNodes, rootSelectorOrNode);
|
||||||
return new ComponentRef_(hostElement, this._componentType);
|
return new ComponentRef_(hostElement, this._componentType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import {Key, Injector, ResolvedProvider, Provider, provide, Injectable} from 'angular2/src/core/di';
|
import {Key, Injector, ResolvedProvider, Provider, provide, Injectable} from 'angular2/src/core/di';
|
||||||
import {ComponentResolver} from './component_resolver';
|
import {ComponentResolver} from './component_resolver';
|
||||||
import {isType, Type, stringify, isPresent} from 'angular2/src/facade/lang';
|
import {isType, Type, stringify, isPresent} from 'angular2/src/facade/lang';
|
||||||
import {AppViewManager} from 'angular2/src/core/linker/view_manager';
|
|
||||||
import {ElementRef, ElementRef_} from './element_ref';
|
|
||||||
import {ComponentRef} from './component_factory';
|
import {ComponentRef} from './component_factory';
|
||||||
|
import {ViewContainerRef} from './view_container_ref';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for instantiating a Component and attaching it to a View at a specified location.
|
* Service for instantiating a Component and attaching it to a View at a specified location.
|
||||||
|
@ -61,60 +60,9 @@ export abstract class DynamicComponentLoader {
|
||||||
abstract loadAsRoot(type: Type, overrideSelectorOrNode: string | any, injector: Injector,
|
abstract loadAsRoot(type: Type, overrideSelectorOrNode: string | any, injector: Injector,
|
||||||
onDispose?: () => void, projectableNodes?: any[][]): Promise<ComponentRef>;
|
onDispose?: () => void, projectableNodes?: any[][]): Promise<ComponentRef>;
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an instance of a Component and attaches it to a View Container located inside of the
|
|
||||||
* Component View of another Component instance.
|
|
||||||
*
|
|
||||||
* The targeted Component Instance is specified via its `hostLocation` {@link ElementRef}. The
|
|
||||||
* location within the Component View of this Component Instance is specified via `anchorName`
|
|
||||||
* Template Variable Name.
|
|
||||||
*
|
|
||||||
* You can optionally provide `providers` to configure the {@link Injector} provisioned for this
|
|
||||||
* Component Instance.
|
|
||||||
*
|
|
||||||
* Returns a promise for the {@link ComponentRef} representing the newly created Component.
|
|
||||||
*
|
|
||||||
* ### Example
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* @Component({
|
|
||||||
* selector: 'child-component',
|
|
||||||
* template: 'Child'
|
|
||||||
* })
|
|
||||||
* class ChildComponent {
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* @Component({
|
|
||||||
* selector: 'my-app',
|
|
||||||
* template: 'Parent (<div #child></div>)'
|
|
||||||
* })
|
|
||||||
* class MyApp {
|
|
||||||
* constructor(dcl: DynamicComponentLoader, elementRef: ElementRef) {
|
|
||||||
* dcl.loadIntoLocation(ChildComponent, elementRef, 'child');
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* bootstrap(MyApp);
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Resulting DOM:
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* <my-app>
|
|
||||||
* Parent (
|
|
||||||
* <div #child="" class="ng-binding"></div>
|
|
||||||
* <child-component class="ng-binding">Child</child-component>
|
|
||||||
* )
|
|
||||||
* </my-app>
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
abstract loadIntoLocation(type: Type, hostLocation: ElementRef, anchorName: string,
|
|
||||||
providers?: ResolvedProvider[],
|
|
||||||
projectableNodes?: any[][]): Promise<ComponentRef>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of a Component and attaches it to the View Container found at the
|
* Creates an instance of a Component and attaches it to the View Container found at the
|
||||||
* `location` specified as {@link ElementRef}.
|
* `location` specified as {@link ViewContainerRef}.
|
||||||
*
|
*
|
||||||
* You can optionally provide `providers` to configure the {@link Injector} provisioned for this
|
* You can optionally provide `providers` to configure the {@link Injector} provisioned for this
|
||||||
* Component Instance.
|
* Component Instance.
|
||||||
|
@ -137,8 +85,8 @@ export abstract class DynamicComponentLoader {
|
||||||
* template: 'Parent'
|
* template: 'Parent'
|
||||||
* })
|
* })
|
||||||
* class MyApp {
|
* class MyApp {
|
||||||
* constructor(dcl: DynamicComponentLoader, elementRef: ElementRef) {
|
* constructor(dcl: DynamicComponentLoader, viewContainerRef: ViewContainerRef) {
|
||||||
* dcl.loadNextToLocation(ChildComponent, elementRef);
|
* dcl.loadNextToLocation(ChildComponent, viewContainerRef);
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
|
@ -152,15 +100,14 @@ export abstract class DynamicComponentLoader {
|
||||||
* <child-component>Child</child-component>
|
* <child-component>Child</child-component>
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
abstract loadNextToLocation(type: Type, location: ElementRef, providers?: ResolvedProvider[],
|
abstract loadNextToLocation(type: Type, location: ViewContainerRef,
|
||||||
|
providers?: ResolvedProvider[],
|
||||||
projectableNodes?: any[][]): Promise<ComponentRef>;
|
projectableNodes?: any[][]): Promise<ComponentRef>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DynamicComponentLoader_ extends DynamicComponentLoader {
|
export class DynamicComponentLoader_ extends DynamicComponentLoader {
|
||||||
constructor(private _compiler: ComponentResolver, private _viewManager: AppViewManager) {
|
constructor(private _compiler: ComponentResolver) { super(); }
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
loadAsRoot(type: Type, overrideSelectorOrNode: string | any, injector: Injector,
|
loadAsRoot(type: Type, overrideSelectorOrNode: string | any, injector: Injector,
|
||||||
onDispose?: () => void, projectableNodes?: any[][]): Promise<ComponentRef> {
|
onDispose?: () => void, projectableNodes?: any[][]): Promise<ComponentRef> {
|
||||||
|
@ -175,20 +122,11 @@ export class DynamicComponentLoader_ extends DynamicComponentLoader {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadIntoLocation(type: Type, hostLocation: ElementRef, anchorName: string,
|
loadNextToLocation(type: Type, location: ViewContainerRef, providers: ResolvedProvider[] = null,
|
||||||
providers: ResolvedProvider[] = null,
|
|
||||||
projectableNodes: any[][] = null): Promise<ComponentRef> {
|
|
||||||
return this.loadNextToLocation(
|
|
||||||
type, this._viewManager.getNamedElementInComponentView(hostLocation, anchorName), providers,
|
|
||||||
projectableNodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadNextToLocation(type: Type, location: ElementRef, providers: ResolvedProvider[] = null,
|
|
||||||
projectableNodes: any[][] = null): Promise<ComponentRef> {
|
projectableNodes: any[][] = null): Promise<ComponentRef> {
|
||||||
return this._compiler.resolveComponent(type).then(componentFactory => {
|
return this._compiler.resolveComponent(type).then(componentFactory => {
|
||||||
var viewContainer = this._viewManager.getViewContainer(location);
|
return location.createComponent(componentFactory, location.length, providers,
|
||||||
return viewContainer.createComponent(componentFactory, viewContainer.length, providers,
|
projectableNodes);
|
||||||
projectableNodes);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,37 +6,30 @@ import {Injector} from 'angular2/src/core/di';
|
||||||
|
|
||||||
import {AppView} from './view';
|
import {AppView} from './view';
|
||||||
import {ViewType} from './view_type';
|
import {ViewType} from './view_type';
|
||||||
import {ElementRef_} from './element_ref';
|
import {ElementRef} from './element_ref';
|
||||||
|
|
||||||
import {ViewContainerRef, ViewContainerRef_} from './view_container_ref';
|
import {ViewContainerRef, ViewContainerRef_} from './view_container_ref';
|
||||||
|
|
||||||
import {QueryList} from './query_list';
|
import {QueryList} from './query_list';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An AppElement is created for elements that have a ViewContainerRef,
|
||||||
|
* a nested component or a <template> element to keep data around
|
||||||
|
* that is needed for later instantiations.
|
||||||
|
*/
|
||||||
export class AppElement {
|
export class AppElement {
|
||||||
public nestedViews: AppView<any>[] = null;
|
public nestedViews: AppView<any>[] = null;
|
||||||
public componentView: AppView<any> = null;
|
public componentView: AppView<any> = null;
|
||||||
|
|
||||||
private _ref: ElementRef_;
|
|
||||||
private _vcRef: ViewContainerRef_;
|
|
||||||
public component: any;
|
public component: any;
|
||||||
public componentConstructorViewQueries: QueryList<any>[];
|
public componentConstructorViewQueries: QueryList<any>[];
|
||||||
|
|
||||||
constructor(public index: number, public parentIndex: number, public parentView: AppView<any>,
|
constructor(public index: number, public parentIndex: number, public parentView: AppView<any>,
|
||||||
public nativeElement: any) {}
|
public nativeElement: any) {}
|
||||||
|
|
||||||
get ref(): ElementRef_ {
|
get elementRef(): ElementRef { return new ElementRef(this.nativeElement); }
|
||||||
if (isBlank(this._ref)) {
|
|
||||||
this._ref = new ElementRef_(this);
|
|
||||||
}
|
|
||||||
return this._ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
get vcRef(): ViewContainerRef_ {
|
get vcRef(): ViewContainerRef_ { return new ViewContainerRef_(this); }
|
||||||
if (isBlank(this._vcRef)) {
|
|
||||||
this._vcRef = new ViewContainerRef_(this);
|
|
||||||
}
|
|
||||||
return this._vcRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
initComponent(component: any, componentConstructorViewQueries: QueryList<any>[],
|
initComponent(component: any, componentConstructorViewQueries: QueryList<any>[],
|
||||||
view: AppView<any>) {
|
view: AppView<any>) {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {AppElement} from './element';
|
||||||
// Note: We don't expose things like `Injector`, `ViewContainer`, ... here,
|
// Note: We don't expose things like `Injector`, `ViewContainer`, ... here,
|
||||||
// i.e. users have to ask for what they need. With that, we can build better analysis tools
|
// i.e. users have to ask for what they need. With that, we can build better analysis tools
|
||||||
// and could do better codegen in the future.
|
// and could do better codegen in the future.
|
||||||
export abstract class ElementRef {
|
export class ElementRef {
|
||||||
/**
|
/**
|
||||||
* The underlying native element or `null` if direct access to native elements is not supported
|
* The underlying native element or `null` if direct access to native elements is not supported
|
||||||
* (e.g. when the application runs in a web worker).
|
* (e.g. when the application runs in a web worker).
|
||||||
|
@ -30,13 +30,7 @@ export abstract class ElementRef {
|
||||||
* </p>
|
* </p>
|
||||||
* </div>
|
* </div>
|
||||||
*/
|
*/
|
||||||
get nativeElement(): any { return unimplemented(); }
|
public nativeElement: any;
|
||||||
}
|
|
||||||
|
constructor(nativeElement: any) { this.nativeElement = nativeElement; }
|
||||||
export class ElementRef_ implements ElementRef {
|
|
||||||
constructor(private _element: AppElement) {}
|
|
||||||
|
|
||||||
get internalElement(): AppElement { return this._element; }
|
|
||||||
|
|
||||||
get nativeElement() { return this._element.nativeElement; }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {ElementRef, ElementRef_} from './element_ref';
|
import {ElementRef} from './element_ref';
|
||||||
import {AppElement} from './element';
|
import {AppElement} from './element';
|
||||||
import {AppView} from './view';
|
import {AppView} from './view';
|
||||||
import {EmbeddedViewRef} from './view_ref';
|
import {EmbeddedViewRef} from './view_ref';
|
||||||
|
@ -37,11 +37,11 @@ export class TemplateRef_ extends TemplateRef {
|
||||||
constructor(private _appElement: AppElement, private _viewFactory: Function) { super(); }
|
constructor(private _appElement: AppElement, private _viewFactory: Function) { super(); }
|
||||||
|
|
||||||
createEmbeddedView(): EmbeddedViewRef {
|
createEmbeddedView(): EmbeddedViewRef {
|
||||||
var view: AppView<any> = this._viewFactory(this._appElement.parentView.viewManager,
|
var view: AppView<any> = this._viewFactory(this._appElement.parentView.viewUtils,
|
||||||
this._appElement.parentInjector, this._appElement);
|
this._appElement.parentInjector, this._appElement);
|
||||||
view.create(null, null);
|
view.create(null, null);
|
||||||
return view.ref;
|
return view.ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
get elementRef(): ElementRef { return this._appElement.ref; }
|
get elementRef(): ElementRef { return this._appElement.elementRef; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,9 @@ import {ObservableWrapper} from 'angular2/src/facade/async';
|
||||||
import {Renderer, RootRenderer, RenderComponentType} from 'angular2/src/core/render/api';
|
import {Renderer, RootRenderer, RenderComponentType} from 'angular2/src/core/render/api';
|
||||||
import {ViewRef_} from './view_ref';
|
import {ViewRef_} from './view_ref';
|
||||||
|
|
||||||
import {AppViewManager_, AppViewManager} from './view_manager';
|
|
||||||
import {ViewType} from './view_type';
|
import {ViewType} from './view_type';
|
||||||
import {
|
import {
|
||||||
|
ViewUtils,
|
||||||
flattenNestedViewRenderNodes,
|
flattenNestedViewRenderNodes,
|
||||||
ensureSlotCount,
|
ensureSlotCount,
|
||||||
arrayLooseIdentical,
|
arrayLooseIdentical,
|
||||||
|
@ -65,7 +65,6 @@ export abstract class AppView<T> {
|
||||||
allNodes: any[];
|
allNodes: any[];
|
||||||
disposables: Function[];
|
disposables: Function[];
|
||||||
subscriptions: any[];
|
subscriptions: any[];
|
||||||
namedAppElements: {[key: string]: AppElement};
|
|
||||||
contentChildren: AppView<any>[] = [];
|
contentChildren: AppView<any>[] = [];
|
||||||
viewChildren: AppView<any>[] = [];
|
viewChildren: AppView<any>[] = [];
|
||||||
renderParent: AppView<any>;
|
renderParent: AppView<any>;
|
||||||
|
@ -95,13 +94,13 @@ export abstract class AppView<T> {
|
||||||
private _hasExternalHostElement: boolean;
|
private _hasExternalHostElement: boolean;
|
||||||
|
|
||||||
constructor(public clazz: any, public componentType: RenderComponentType, public type: ViewType,
|
constructor(public clazz: any, public componentType: RenderComponentType, public type: ViewType,
|
||||||
public locals: {[key: string]: any}, public viewManager: AppViewManager_,
|
public locals: {[key: string]: any}, public viewUtils: ViewUtils,
|
||||||
public parentInjector: Injector, public declarationAppElement: AppElement,
|
public parentInjector: Injector, public declarationAppElement: AppElement,
|
||||||
public cdMode: ChangeDetectionStrategy, literalArrayCacheSize: number,
|
public cdMode: ChangeDetectionStrategy, literalArrayCacheSize: number,
|
||||||
literalMapCacheSize: number, public staticNodeDebugInfos: StaticNodeDebugInfo[]) {
|
literalMapCacheSize: number, public staticNodeDebugInfos: StaticNodeDebugInfo[]) {
|
||||||
this.ref = new ViewRef_(this);
|
this.ref = new ViewRef_(this);
|
||||||
if (type === ViewType.COMPONENT || type === ViewType.HOST) {
|
if (type === ViewType.COMPONENT || type === ViewType.HOST) {
|
||||||
this.renderer = viewManager.renderComponent(componentType);
|
this.renderer = viewUtils.renderComponent(componentType);
|
||||||
} else {
|
} else {
|
||||||
this.renderer = declarationAppElement.parentView.renderer;
|
this.renderer = declarationAppElement.parentView.renderer;
|
||||||
}
|
}
|
||||||
|
@ -145,15 +144,15 @@ export abstract class AppView<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overwritten by implementations
|
* Overwritten by implementations.
|
||||||
|
* Returns the AppElement for the host element for ViewType.HOST.
|
||||||
*/
|
*/
|
||||||
createInternal(rootSelectorOrNode: string | any): AppElement { return null; }
|
createInternal(rootSelectorOrNode: string | any): AppElement { return null; }
|
||||||
|
|
||||||
init(rootNodesOrAppElements: any[], allNodes: any[], appElements: {[key: string]: AppElement},
|
init(rootNodesOrAppElements: any[], allNodes: any[], disposables: Function[],
|
||||||
disposables: Function[], subscriptions: any[]) {
|
subscriptions: any[]) {
|
||||||
this.rootNodesOrAppElements = rootNodesOrAppElements;
|
this.rootNodesOrAppElements = rootNodesOrAppElements;
|
||||||
this.allNodes = allNodes;
|
this.allNodes = allNodes;
|
||||||
this.namedAppElements = appElements;
|
|
||||||
this.disposables = disposables;
|
this.disposables = disposables;
|
||||||
this.subscriptions = subscriptions;
|
this.subscriptions = subscriptions;
|
||||||
if (this.type === ViewType.COMPONENT) {
|
if (this.type === ViewType.COMPONENT) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {wtfCreateScope, wtfLeave, WtfScopeFn} from '../profile/profile';
|
||||||
|
|
||||||
import {AppElement} from './element';
|
import {AppElement} from './element';
|
||||||
|
|
||||||
import {ElementRef, ElementRef_} from './element_ref';
|
import {ElementRef} from './element_ref';
|
||||||
import {TemplateRef, TemplateRef_} from './template_ref';
|
import {TemplateRef, TemplateRef_} from './template_ref';
|
||||||
import {EmbeddedViewRef, ViewRef, ViewRef_} from './view_ref';
|
import {EmbeddedViewRef, ViewRef, ViewRef_} from './view_ref';
|
||||||
import {ComponentFactory, ComponentRef} from './component_factory';
|
import {ComponentFactory, ComponentRef} from './component_factory';
|
||||||
|
@ -27,10 +27,7 @@ import {ComponentFactory, ComponentRef} from './component_factory';
|
||||||
* the Rendered View.
|
* the Rendered View.
|
||||||
*
|
*
|
||||||
* To access a `ViewContainerRef` of an Element, you can either place a {@link Directive} injected
|
* To access a `ViewContainerRef` of an Element, you can either place a {@link Directive} injected
|
||||||
* with `ViewContainerRef` on the Element, or you obtain it via
|
* with `ViewContainerRef` on the Element, or you obtain it via a {@link ViewChild} query.
|
||||||
* {@link AppViewManager#getViewContainer}.
|
|
||||||
*
|
|
||||||
* <!-- TODO(i): we are also considering ElementRef#viewContainer api -->
|
|
||||||
*/
|
*/
|
||||||
export abstract class ViewContainerRef {
|
export abstract class ViewContainerRef {
|
||||||
/**
|
/**
|
||||||
|
@ -121,7 +118,7 @@ export class ViewContainerRef_ implements ViewContainerRef {
|
||||||
return isPresent(views) ? views.length : 0;
|
return isPresent(views) ? views.length : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
get element(): ElementRef { return this._element.ref; }
|
get element(): ElementRef { return this._element.elementRef; }
|
||||||
|
|
||||||
// TODO(rado): profile and decide whether bounds checks should be added
|
// TODO(rado): profile and decide whether bounds checks should be added
|
||||||
// to the methods below.
|
// to the methods below.
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
import {
|
|
||||||
Injector,
|
|
||||||
Inject,
|
|
||||||
Provider,
|
|
||||||
Injectable,
|
|
||||||
ResolvedProvider,
|
|
||||||
forwardRef
|
|
||||||
} from 'angular2/src/core/di';
|
|
||||||
import {isPresent, isBlank, isArray, Type} from 'angular2/src/facade/lang';
|
|
||||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
|
||||||
import {ElementRef, ElementRef_} from './element_ref';
|
|
||||||
import {ViewContainerRef, ViewContainerRef_} from './view_container_ref';
|
|
||||||
import {RootRenderer, RenderComponentType, Renderer} from 'angular2/src/core/render/api';
|
|
||||||
import {APP_ID} from 'angular2/src/core/application_tokens';
|
|
||||||
import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Service exposing low level API for creating, moving and destroying Views.
|
|
||||||
*
|
|
||||||
* Most applications should use higher-level abstractions like {@link DynamicComponentLoader} and
|
|
||||||
* {@link ViewContainerRef} instead.
|
|
||||||
*/
|
|
||||||
export abstract class AppViewManager {
|
|
||||||
/**
|
|
||||||
* Returns a {@link ViewContainerRef} of the View Container at the specified location.
|
|
||||||
*/
|
|
||||||
abstract getViewContainer(location: ElementRef): ViewContainerRef;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Searches the Component View of the Component specified via `hostLocation` and returns the
|
|
||||||
* {@link ElementRef} for the Element identified via a Variable Name `variableName`.
|
|
||||||
*
|
|
||||||
* Throws an exception if the specified `hostLocation` is not a Host Element of a Component, or if
|
|
||||||
* variable `variableName` couldn't be found in the Component View of this Component.
|
|
||||||
*/
|
|
||||||
abstract getNamedElementInComponentView(hostLocation: ElementRef,
|
|
||||||
variableName: string): ElementRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class AppViewManager_ extends AppViewManager {
|
|
||||||
private _nextCompTypeId: number = 0;
|
|
||||||
|
|
||||||
constructor(private _renderer: RootRenderer, @Inject(APP_ID) private _appId: string) { super(); }
|
|
||||||
|
|
||||||
getViewContainer(location: ElementRef): ViewContainerRef {
|
|
||||||
return (<ElementRef_>location).internalElement.vcRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
getNamedElementInComponentView(hostLocation: ElementRef, variableName: string): ElementRef {
|
|
||||||
var appEl = (<ElementRef_>hostLocation).internalElement;
|
|
||||||
var componentView = appEl.componentView;
|
|
||||||
if (isBlank(componentView)) {
|
|
||||||
throw new BaseException(`There is no component directive at element ${hostLocation}`);
|
|
||||||
}
|
|
||||||
var el = componentView.namedAppElements[variableName];
|
|
||||||
if (isPresent(el)) {
|
|
||||||
return el.ref;
|
|
||||||
}
|
|
||||||
throw new BaseException(`Could not find variable ${variableName}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by the generated code
|
|
||||||
*/
|
|
||||||
createRenderComponentType(templateUrl: string, slotCount: number,
|
|
||||||
encapsulation: ViewEncapsulation,
|
|
||||||
styles: Array<string | any[]>): RenderComponentType {
|
|
||||||
return new RenderComponentType(`${this._appId}-${this._nextCompTypeId++}`, templateUrl,
|
|
||||||
slotCount, encapsulation, styles);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
renderComponent(renderComponentType: RenderComponentType): Renderer {
|
|
||||||
return this._renderer.renderComponent(renderComponentType);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,6 +11,32 @@ import {BaseException} from 'angular2/src/facade/exceptions';
|
||||||
import {AppElement} from './element';
|
import {AppElement} from './element';
|
||||||
import {ExpressionChangedAfterItHasBeenCheckedException} from './exceptions';
|
import {ExpressionChangedAfterItHasBeenCheckedException} from './exceptions';
|
||||||
import {devModeEqual} from 'angular2/src/core/change_detection/change_detection';
|
import {devModeEqual} from 'angular2/src/core/change_detection/change_detection';
|
||||||
|
import {Inject, Injectable} from 'angular2/src/core/di';
|
||||||
|
import {RootRenderer, RenderComponentType, Renderer} from 'angular2/src/core/render/api';
|
||||||
|
import {APP_ID} from 'angular2/src/core/application_tokens';
|
||||||
|
import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ViewUtils {
|
||||||
|
private _nextCompTypeId: number = 0;
|
||||||
|
|
||||||
|
constructor(private _renderer: RootRenderer, @Inject(APP_ID) private _appId: string) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by the generated code
|
||||||
|
*/
|
||||||
|
createRenderComponentType(templateUrl: string, slotCount: number,
|
||||||
|
encapsulation: ViewEncapsulation,
|
||||||
|
styles: Array<string | any[]>): RenderComponentType {
|
||||||
|
return new RenderComponentType(`${this._appId}-${this._nextCompTypeId++}`, templateUrl,
|
||||||
|
slotCount, encapsulation, styles);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
renderComponent(renderComponentType: RenderComponentType): Renderer {
|
||||||
|
return this._renderer.renderComponent(renderComponentType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function flattenNestedViewRenderNodes(nodes: any[]): any[] {
|
export function flattenNestedViewRenderNodes(nodes: any[]): any[] {
|
||||||
return _flattenNestedViewRenderNodes(nodes, []);
|
return _flattenNestedViewRenderNodes(nodes, []);
|
||||||
|
|
|
@ -145,8 +145,9 @@ class Attribute extends AttributeMetadata {
|
||||||
*/
|
*/
|
||||||
@Deprecated("Use ContentChildren/ContentChild instead")
|
@Deprecated("Use ContentChildren/ContentChild instead")
|
||||||
class Query extends QueryMetadata {
|
class Query extends QueryMetadata {
|
||||||
const Query(dynamic /*Type | string*/ selector, {bool descendants: false})
|
const Query(dynamic /*Type | string*/ selector,
|
||||||
: super(selector, descendants: descendants);
|
{bool descendants: false, dynamic read: null})
|
||||||
|
: super(selector, descendants: descendants, read: read);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,15 +155,15 @@ class Query extends QueryMetadata {
|
||||||
*/
|
*/
|
||||||
class ContentChildren extends ContentChildrenMetadata {
|
class ContentChildren extends ContentChildrenMetadata {
|
||||||
const ContentChildren(dynamic /*Type | string*/ selector,
|
const ContentChildren(dynamic /*Type | string*/ selector,
|
||||||
{bool descendants: false})
|
{bool descendants: false, dynamic read: null})
|
||||||
: super(selector, descendants: descendants);
|
: super(selector, descendants: descendants, read: read);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See: [ContentChildMetadata] for docs.
|
* See: [ContentChildMetadata] for docs.
|
||||||
*/
|
*/
|
||||||
class ContentChild extends ContentChildMetadata {
|
class ContentChild extends ContentChildMetadata {
|
||||||
const ContentChild(dynamic /*Type | string*/ selector) : super(selector);
|
const ContentChild(dynamic /*Type | string*/ selector, {dynamic read: null}) : super(selector, read: read);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -170,22 +171,22 @@ class ContentChild extends ContentChildMetadata {
|
||||||
*/
|
*/
|
||||||
@Deprecated("Use ViewChildren/ViewChild instead")
|
@Deprecated("Use ViewChildren/ViewChild instead")
|
||||||
class ViewQuery extends ViewQueryMetadata {
|
class ViewQuery extends ViewQueryMetadata {
|
||||||
const ViewQuery(dynamic /*Type | string*/ selector)
|
const ViewQuery(dynamic /*Type | string*/ selector, {dynamic read: null})
|
||||||
: super(selector, descendants: true);
|
: super(selector, descendants: true, read: read);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See: [ViewChildrenMetadata] for docs.
|
* See: [ViewChildrenMetadata] for docs.
|
||||||
*/
|
*/
|
||||||
class ViewChildren extends ViewChildrenMetadata {
|
class ViewChildren extends ViewChildrenMetadata {
|
||||||
const ViewChildren(dynamic /*Type | string*/ selector) : super(selector);
|
const ViewChildren(dynamic /*Type | string*/ selector, {dynamic read: null}) : super(selector, read: read);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See: [ViewChildMetadata] for docs.
|
* See: [ViewChildMetadata] for docs.
|
||||||
*/
|
*/
|
||||||
class ViewChild extends ViewChildMetadata {
|
class ViewChild extends ViewChildMetadata {
|
||||||
const ViewChild(dynamic /*Type | string*/ selector) : super(selector);
|
const ViewChild(dynamic /*Type | string*/ selector, {dynamic read: null}) : super(selector, read: read);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -402,40 +402,43 @@ export interface AttributeMetadataFactory {
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export interface QueryMetadataFactory {
|
export interface QueryMetadataFactory {
|
||||||
(selector: Type | string, {descendants}?: {descendants?: boolean}): ParameterDecorator;
|
(selector: Type | string,
|
||||||
new (selector: Type | string, {descendants}?: {descendants?: boolean}): QueryMetadata;
|
{descendants, read}?: {descendants?: boolean, read?: any}): ParameterDecorator;
|
||||||
|
new (selector: Type | string,
|
||||||
|
{descendants, read}?: {descendants?: boolean, read?: any}): QueryMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory for {@link ContentChildren}.
|
* Factory for {@link ContentChildren}.
|
||||||
*/
|
*/
|
||||||
export interface ContentChildrenMetadataFactory {
|
export interface ContentChildrenMetadataFactory {
|
||||||
(selector: Type | string, {descendants}?: {descendants?: boolean}): any;
|
(selector: Type | string, {descendants, read}?: {descendants?: boolean, read?: any}): any;
|
||||||
new (selector: Type | string, {descendants}?: {descendants?: boolean}): ContentChildrenMetadata;
|
new (selector: Type | string,
|
||||||
|
{descendants, read}?: {descendants?: boolean, read?: any}): ContentChildrenMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory for {@link ContentChild}.
|
* Factory for {@link ContentChild}.
|
||||||
*/
|
*/
|
||||||
export interface ContentChildMetadataFactory {
|
export interface ContentChildMetadataFactory {
|
||||||
(selector: Type | string): any;
|
(selector: Type | string, {read}?: {read?: any}): any;
|
||||||
new (selector: Type | string): ContentChildMetadataFactory;
|
new (selector: Type | string, {read}?: {read?: any}): ContentChildMetadataFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory for {@link ViewChildren}.
|
* Factory for {@link ViewChildren}.
|
||||||
*/
|
*/
|
||||||
export interface ViewChildrenMetadataFactory {
|
export interface ViewChildrenMetadataFactory {
|
||||||
(selector: Type | string): any;
|
(selector: Type | string, {read}?: {read?: any}): any;
|
||||||
new (selector: Type | string): ViewChildrenMetadata;
|
new (selector: Type | string, {read}?: {read?: any}): ViewChildrenMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory for {@link ViewChild}.
|
* Factory for {@link ViewChild}.
|
||||||
*/
|
*/
|
||||||
export interface ViewChildMetadataFactory {
|
export interface ViewChildMetadataFactory {
|
||||||
(selector: Type | string): any;
|
(selector: Type | string, {read}?: {read?: any}): any;
|
||||||
new (selector: Type | string): ViewChildMetadataFactory;
|
new (selector: Type | string, {read}?: {read?: any}): ViewChildMetadataFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -149,12 +149,18 @@ export class QueryMetadata extends DependencyMetadata {
|
||||||
*/
|
*/
|
||||||
descendants: boolean;
|
descendants: boolean;
|
||||||
first: boolean;
|
first: boolean;
|
||||||
|
/**
|
||||||
|
* The DI token to read from an element that matches the selector.
|
||||||
|
*/
|
||||||
|
read: any;
|
||||||
|
|
||||||
constructor(private _selector: Type | string,
|
constructor(private _selector: Type | string,
|
||||||
{descendants = false, first = false}: {descendants?: boolean, first?: boolean} = {}) {
|
{descendants = false, first = false,
|
||||||
|
read = null}: {descendants?: boolean, first?: boolean, read?: any} = {}) {
|
||||||
super();
|
super();
|
||||||
this.descendants = descendants;
|
this.descendants = descendants;
|
||||||
this.first = first;
|
this.first = first;
|
||||||
|
this.read = read;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -204,8 +210,9 @@ export class QueryMetadata extends DependencyMetadata {
|
||||||
*/
|
*/
|
||||||
@CONST()
|
@CONST()
|
||||||
export class ContentChildrenMetadata extends QueryMetadata {
|
export class ContentChildrenMetadata extends QueryMetadata {
|
||||||
constructor(_selector: Type | string, {descendants = false}: {descendants?: boolean} = {}) {
|
constructor(_selector: Type | string,
|
||||||
super(_selector, {descendants: descendants});
|
{descendants = false, read = null}: {descendants?: boolean, read?: any} = {}) {
|
||||||
|
super(_selector, {descendants: descendants, read: read});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +239,9 @@ export class ContentChildrenMetadata extends QueryMetadata {
|
||||||
*/
|
*/
|
||||||
@CONST()
|
@CONST()
|
||||||
export class ContentChildMetadata extends QueryMetadata {
|
export class ContentChildMetadata extends QueryMetadata {
|
||||||
constructor(_selector: Type | string) { super(_selector, {descendants: true, first: true}); }
|
constructor(_selector: Type | string, {read = null}: {read?: any} = {}) {
|
||||||
|
super(_selector, {descendants: true, first: true, read: read});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -273,8 +282,9 @@ export class ContentChildMetadata extends QueryMetadata {
|
||||||
@CONST()
|
@CONST()
|
||||||
export class ViewQueryMetadata extends QueryMetadata {
|
export class ViewQueryMetadata extends QueryMetadata {
|
||||||
constructor(_selector: Type | string,
|
constructor(_selector: Type | string,
|
||||||
{descendants = false, first = false}: {descendants?: boolean, first?: boolean} = {}) {
|
{descendants = false, first = false,
|
||||||
super(_selector, {descendants: descendants, first: first});
|
read = null}: {descendants?: boolean, first?: boolean, read?: any} = {}) {
|
||||||
|
super(_selector, {descendants: descendants, first: first, read: read});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -363,7 +373,9 @@ export class ViewQueryMetadata extends QueryMetadata {
|
||||||
*/
|
*/
|
||||||
@CONST()
|
@CONST()
|
||||||
export class ViewChildrenMetadata extends ViewQueryMetadata {
|
export class ViewChildrenMetadata extends ViewQueryMetadata {
|
||||||
constructor(_selector: Type | string) { super(_selector, {descendants: true}); }
|
constructor(_selector: Type | string, {read = null}: {read?: any} = {}) {
|
||||||
|
super(_selector, {descendants: true, read: read});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -438,5 +450,7 @@ export class ViewChildrenMetadata extends ViewQueryMetadata {
|
||||||
*/
|
*/
|
||||||
@CONST()
|
@CONST()
|
||||||
export class ViewChildMetadata extends ViewQueryMetadata {
|
export class ViewChildMetadata extends ViewQueryMetadata {
|
||||||
constructor(_selector: Type | string) { super(_selector, {descendants: true, first: true}); }
|
constructor(_selector: Type | string, {read = null}: {read?: any} = {}) {
|
||||||
|
super(_selector, {descendants: true, first: true, read: read});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,8 +186,8 @@ export class RouterLinkTransform implements TemplateAstVisitor {
|
||||||
let updatedInputs = ast.inputs.map(c => c.visit(this, context));
|
let updatedInputs = ast.inputs.map(c => c.visit(this, context));
|
||||||
let updatedDirectives = ast.directives.map(c => c.visit(this, context));
|
let updatedDirectives = ast.directives.map(c => c.visit(this, context));
|
||||||
return new ElementAst(ast.name, ast.attrs, updatedInputs, ast.outputs, ast.exportAsVars,
|
return new ElementAst(ast.name, ast.attrs, updatedInputs, ast.outputs, ast.exportAsVars,
|
||||||
updatedDirectives, ast.providers, updatedChildren, ast.ngContentIndex,
|
updatedDirectives, ast.providers, ast.hasViewContainer, updatedChildren,
|
||||||
ast.sourceSpan);
|
ast.ngContentIndex, ast.sourceSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
visitVariable(ast: any, context: any): any { return ast; }
|
visitVariable(ast: any, context: any): any { return ast; }
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
Attribute,
|
Attribute,
|
||||||
DynamicComponentLoader,
|
DynamicComponentLoader,
|
||||||
ComponentRef,
|
ComponentRef,
|
||||||
ElementRef,
|
ViewContainerRef,
|
||||||
Injector,
|
Injector,
|
||||||
provide,
|
provide,
|
||||||
Dependency,
|
Dependency,
|
||||||
|
@ -40,7 +40,7 @@ export class RouterOutlet implements OnDestroy {
|
||||||
|
|
||||||
@Output('activate') public activateEvents = new EventEmitter<any>();
|
@Output('activate') public activateEvents = new EventEmitter<any>();
|
||||||
|
|
||||||
constructor(private _elementRef: ElementRef, private _loader: DynamicComponentLoader,
|
constructor(private _viewContainerRef: ViewContainerRef, private _loader: DynamicComponentLoader,
|
||||||
private _parentRouter: routerMod.Router, @Attribute('name') nameAttr: string) {
|
private _parentRouter: routerMod.Router, @Attribute('name') nameAttr: string) {
|
||||||
if (isPresent(nameAttr)) {
|
if (isPresent(nameAttr)) {
|
||||||
this.name = nameAttr;
|
this.name = nameAttr;
|
||||||
|
@ -66,7 +66,7 @@ export class RouterOutlet implements OnDestroy {
|
||||||
provide(routerMod.Router, {useValue: childRouter})
|
provide(routerMod.Router, {useValue: childRouter})
|
||||||
]);
|
]);
|
||||||
this._componentRef =
|
this._componentRef =
|
||||||
this._loader.loadNextToLocation(componentType, this._elementRef, providers);
|
this._loader.loadNextToLocation(componentType, this._viewContainerRef, providers);
|
||||||
return this._componentRef.then((componentRef) => {
|
return this._componentRef.then((componentRef) => {
|
||||||
this.activateEvents.emit(componentRef.instance);
|
this.activateEvents.emit(componentRef.instance);
|
||||||
if (hasLifecycleHook(hookMod.routerOnActivate, componentType)) {
|
if (hasLifecycleHook(hookMod.routerOnActivate, componentType)) {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
export const NG2_APP_VIEW_MANAGER = 'ng2.AppViewManager';
|
|
||||||
export const NG2_COMPILER = 'ng2.Compiler';
|
export const NG2_COMPILER = 'ng2.Compiler';
|
||||||
export const NG2_INJECTOR = 'ng2.Injector';
|
export const NG2_INJECTOR = 'ng2.Injector';
|
||||||
export const NG2_COMPONENT_FACTORY_REF_MAP = 'ng2.ComponentFactoryRefMap';
|
export const NG2_COMPONENT_FACTORY_REF_MAP = 'ng2.ComponentFactoryRefMap';
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import {
|
import {
|
||||||
provide,
|
provide,
|
||||||
AppViewManager,
|
|
||||||
ChangeDetectorRef,
|
ChangeDetectorRef,
|
||||||
Injector,
|
Injector,
|
||||||
OnChanges,
|
OnChanges,
|
||||||
|
@ -30,8 +29,7 @@ export class DowngradeNg2ComponentAdapter {
|
||||||
constructor(private id: string, private info: ComponentInfo,
|
constructor(private id: string, private info: ComponentInfo,
|
||||||
private element: angular.IAugmentedJQuery, private attrs: angular.IAttributes,
|
private element: angular.IAugmentedJQuery, private attrs: angular.IAttributes,
|
||||||
private scope: angular.IScope, private parentInjector: Injector,
|
private scope: angular.IScope, private parentInjector: Injector,
|
||||||
private parse: angular.IParseService, private viewManager: AppViewManager,
|
private parse: angular.IParseService, private componentFactory: ComponentFactory) {
|
||||||
private componentFactory: ComponentFactory) {
|
|
||||||
(<any>this.element[0]).id = id;
|
(<any>this.element[0]).id = id;
|
||||||
this.componentScope = scope.$new();
|
this.componentScope = scope.$new();
|
||||||
this.childNodes = <Node[]><any>element.contents();
|
this.childNodes = <Node[]><any>element.contents();
|
||||||
|
|
|
@ -2,7 +2,6 @@ import {
|
||||||
provide,
|
provide,
|
||||||
platform,
|
platform,
|
||||||
ApplicationRef,
|
ApplicationRef,
|
||||||
AppViewManager,
|
|
||||||
ComponentResolver,
|
ComponentResolver,
|
||||||
Injector,
|
Injector,
|
||||||
NgZone,
|
NgZone,
|
||||||
|
@ -26,7 +25,6 @@ import {
|
||||||
NG1_ROOT_SCOPE,
|
NG1_ROOT_SCOPE,
|
||||||
NG1_SCOPE,
|
NG1_SCOPE,
|
||||||
NG1_TESTABILITY,
|
NG1_TESTABILITY,
|
||||||
NG2_APP_VIEW_MANAGER,
|
|
||||||
NG2_COMPILER,
|
NG2_COMPILER,
|
||||||
NG2_INJECTOR,
|
NG2_INJECTOR,
|
||||||
NG2_COMPONENT_FACTORY_REF_MAP,
|
NG2_COMPONENT_FACTORY_REF_MAP,
|
||||||
|
@ -318,7 +316,6 @@ export class UpgradeAdapter {
|
||||||
.value(NG2_ZONE, ngZone)
|
.value(NG2_ZONE, ngZone)
|
||||||
.value(NG2_COMPILER, compiler)
|
.value(NG2_COMPILER, compiler)
|
||||||
.value(NG2_COMPONENT_FACTORY_REF_MAP, componentFactoryRefMap)
|
.value(NG2_COMPONENT_FACTORY_REF_MAP, componentFactoryRefMap)
|
||||||
.value(NG2_APP_VIEW_MANAGER, injector.get(AppViewManager))
|
|
||||||
.config([
|
.config([
|
||||||
'$provide',
|
'$provide',
|
||||||
(provide) => {
|
(provide) => {
|
||||||
|
@ -542,10 +539,8 @@ interface ComponentFactoryRefMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
function ng1ComponentDirective(info: ComponentInfo, idPrefix: string): Function {
|
function ng1ComponentDirective(info: ComponentInfo, idPrefix: string): Function {
|
||||||
(<any>directiveFactory).$inject =
|
(<any>directiveFactory).$inject = [NG2_COMPONENT_FACTORY_REF_MAP, NG1_PARSE];
|
||||||
[NG2_COMPONENT_FACTORY_REF_MAP, NG2_APP_VIEW_MANAGER, NG1_PARSE];
|
|
||||||
function directiveFactory(componentFactoryRefMap: ComponentFactoryRefMap,
|
function directiveFactory(componentFactoryRefMap: ComponentFactoryRefMap,
|
||||||
viewManager: AppViewManager,
|
|
||||||
parse: angular.IParseService): angular.IDirective {
|
parse: angular.IParseService): angular.IDirective {
|
||||||
var componentFactory: ComponentFactory = componentFactoryRefMap[info.selector];
|
var componentFactory: ComponentFactory = componentFactoryRefMap[info.selector];
|
||||||
if (!componentFactory) throw new Error('Expecting ComponentFactory for: ' + info.selector);
|
if (!componentFactory) throw new Error('Expecting ComponentFactory for: ' + info.selector);
|
||||||
|
@ -557,9 +552,9 @@ function ng1ComponentDirective(info: ComponentInfo, idPrefix: string): Function
|
||||||
post: (scope: angular.IScope, element: angular.IAugmentedJQuery, attrs: angular.IAttributes,
|
post: (scope: angular.IScope, element: angular.IAugmentedJQuery, attrs: angular.IAttributes,
|
||||||
parentInjector: any, transclude: angular.ITranscludeFunction): void => {
|
parentInjector: any, transclude: angular.ITranscludeFunction): void => {
|
||||||
var domElement = <any>element[0];
|
var domElement = <any>element[0];
|
||||||
var facade = new DowngradeNg2ComponentAdapter(idPrefix + (idCount++), info, element,
|
var facade =
|
||||||
attrs, scope, <Injector>parentInjector,
|
new DowngradeNg2ComponentAdapter(idPrefix + (idCount++), info, element, attrs, scope,
|
||||||
parse, viewManager, componentFactory);
|
<Injector>parentInjector, parse, componentFactory);
|
||||||
facade.setupInputs();
|
facade.setupInputs();
|
||||||
facade.bootstrapNg2();
|
facade.bootstrapNg2();
|
||||||
facade.projectContent();
|
facade.projectContent();
|
||||||
|
|
|
@ -1506,7 +1506,8 @@ class FooAstTransformer implements TemplateAstVisitor {
|
||||||
visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any { throw 'not implemented'; }
|
visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any { throw 'not implemented'; }
|
||||||
visitElement(ast: ElementAst, context: any): any {
|
visitElement(ast: ElementAst, context: any): any {
|
||||||
if (ast.name != 'div') return ast;
|
if (ast.name != 'div') return ast;
|
||||||
return new ElementAst('foo', [], [], [], [], [], [], [], ast.ngContentIndex, ast.sourceSpan);
|
return new ElementAst('foo', [], [], [], [], [], [], false, [], ast.ngContentIndex,
|
||||||
|
ast.sourceSpan);
|
||||||
}
|
}
|
||||||
visitVariable(ast: VariableAst, context: any): any { throw 'not implemented'; }
|
visitVariable(ast: VariableAst, context: any): any { throw 'not implemented'; }
|
||||||
visitEvent(ast: BoundEventAst, context: any): any { throw 'not implemented'; }
|
visitEvent(ast: BoundEventAst, context: any): any { throw 'not implemented'; }
|
||||||
|
@ -1523,6 +1524,7 @@ class FooAstTransformer implements TemplateAstVisitor {
|
||||||
class BarAstTransformer extends FooAstTransformer {
|
class BarAstTransformer extends FooAstTransformer {
|
||||||
visitElement(ast: ElementAst, context: any): any {
|
visitElement(ast: ElementAst, context: any): any {
|
||||||
if (ast.name != 'foo') return ast;
|
if (ast.name != 'foo') return ast;
|
||||||
return new ElementAst('bar', [], [], [], [], [], [], [], ast.ngContentIndex, ast.sourceSpan);
|
return new ElementAst('bar', [], [], [], [], [], [], false, [], ast.ngContentIndex,
|
||||||
|
ast.sourceSpan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,11 @@ import {
|
||||||
} from 'angular2/testing_internal';
|
} from 'angular2/testing_internal';
|
||||||
|
|
||||||
import {Predicate} from 'angular2/src/facade/collection';
|
import {Predicate} from 'angular2/src/facade/collection';
|
||||||
import {Injector, OnDestroy, DebugElement, Type} from 'angular2/core';
|
import {Injector, OnDestroy, DebugElement, Type, ViewContainerRef, ViewChild} from 'angular2/core';
|
||||||
import {NgIf} from 'angular2/common';
|
import {NgIf} from 'angular2/common';
|
||||||
import {Component, ViewMetadata} from 'angular2/src/core/metadata';
|
import {Component, ViewMetadata} from 'angular2/src/core/metadata';
|
||||||
import {DynamicComponentLoader} from 'angular2/src/core/linker/dynamic_component_loader';
|
import {DynamicComponentLoader} from 'angular2/src/core/linker/dynamic_component_loader';
|
||||||
import {ElementRef, ElementRef_} from 'angular2/src/core/linker/element_ref';
|
import {ElementRef} from 'angular2/src/core/linker/element_ref';
|
||||||
import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
|
import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
|
||||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||||
|
@ -29,266 +29,112 @@ import {PromiseWrapper} from 'angular2/src/facade/promise';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('DynamicComponentLoader', function() {
|
describe('DynamicComponentLoader', function() {
|
||||||
describe("loading into a location", () => {
|
describe("loading next to a location", () => {
|
||||||
it('should work',
|
it('should work',
|
||||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||||
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
||||||
tcb.overrideView(
|
tcb.createAsync(MyComp).then((tc) => {
|
||||||
MyComp,
|
tc.detectChanges();
|
||||||
new ViewMetadata(
|
loader.loadNextToLocation(DynamicallyLoaded,
|
||||||
{template: '<location #loc></location>', directives: [Location]}))
|
tc.componentInstance.viewContainerRef)
|
||||||
.createAsync(MyComp)
|
.then(ref => {
|
||||||
.then((tc) => {
|
expect(tc.debugElement.nativeElement).toHaveText('DynamicallyLoaded;');
|
||||||
loader.loadIntoLocation(DynamicallyLoaded, tc.elementRef, 'loc')
|
|
||||||
.then(ref => {
|
async.done();
|
||||||
expect(tc.debugElement.nativeElement)
|
});
|
||||||
.toHaveText("Location;DynamicallyLoaded;");
|
});
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should return a disposable component ref',
|
it('should return a disposable component ref',
|
||||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
|
||||||
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
|
||||||
tcb.overrideView(
|
|
||||||
MyComp,
|
|
||||||
new ViewMetadata(
|
|
||||||
{template: '<location #loc></location>', directives: [Location]}))
|
|
||||||
.createAsync(MyComp)
|
|
||||||
.then((tc) => {
|
|
||||||
|
|
||||||
loader.loadIntoLocation(DynamicallyLoaded, tc.elementRef, 'loc')
|
|
||||||
.then(ref => {
|
|
||||||
ref.destroy();
|
|
||||||
expect(tc.debugElement.nativeElement).toHaveText("Location;");
|
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should allow to destroy even if the location has been removed',
|
|
||||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
|
||||||
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
|
||||||
tcb.overrideView(MyComp, new ViewMetadata({
|
|
||||||
template: '<child-cmp *ngIf="ctxBoolProp"></child-cmp>',
|
|
||||||
directives: [NgIf, ChildComp]
|
|
||||||
}))
|
|
||||||
.overrideView(
|
|
||||||
ChildComp,
|
|
||||||
new ViewMetadata(
|
|
||||||
{template: '<location #loc></location>', directives: [Location]}))
|
|
||||||
.createAsync(MyComp)
|
|
||||||
.then((tc) => {
|
|
||||||
tc.debugElement.componentInstance.ctxBoolProp = true;
|
|
||||||
tc.detectChanges();
|
|
||||||
var childElementRef = tc.debugElement.query(filterByDirective(ChildComp))
|
|
||||||
.inject(ChildComp)
|
|
||||||
.elementRef;
|
|
||||||
loader.loadIntoLocation(DynamicallyLoaded, childElementRef, 'loc')
|
|
||||||
.then(ref => {
|
|
||||||
expect(tc.debugElement.nativeElement)
|
|
||||||
.toHaveText("Location;DynamicallyLoaded;");
|
|
||||||
|
|
||||||
tc.debugElement.componentInstance.ctxBoolProp = false;
|
|
||||||
tc.detectChanges();
|
|
||||||
expect(tc.debugElement.nativeElement).toHaveText("");
|
|
||||||
|
|
||||||
ref.destroy();
|
|
||||||
expect(tc.debugElement.nativeElement).toHaveText("");
|
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should update host properties',
|
|
||||||
inject(
|
inject(
|
||||||
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||||
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
||||||
tcb.overrideView(
|
tcb.createAsync(MyComp).then((tc) => {
|
||||||
MyComp, new ViewMetadata(
|
tc.detectChanges();
|
||||||
{template: '<location #loc></location>', directives: [Location]}))
|
loader.loadNextToLocation(DynamicallyLoaded, tc.componentInstance.viewContainerRef)
|
||||||
.createAsync(MyComp)
|
.then(ref => {
|
||||||
.then((tc) => {
|
loader.loadNextToLocation(DynamicallyLoaded2,
|
||||||
loader.loadIntoLocation(DynamicallyLoadedWithHostProps, tc.elementRef, 'loc')
|
tc.componentInstance.viewContainerRef)
|
||||||
.then(ref => {
|
.then(ref2 => {
|
||||||
ref.instance.id = "new value";
|
expect(tc.debugElement.nativeElement)
|
||||||
|
.toHaveText("DynamicallyLoaded;DynamicallyLoaded2;");
|
||||||
|
|
||||||
tc.detectChanges();
|
ref2.destroy();
|
||||||
|
|
||||||
var newlyInsertedElement =
|
expect(tc.debugElement.nativeElement).toHaveText("DynamicallyLoaded;");
|
||||||
DOM.childNodes(tc.debugElement.nativeElement)[1];
|
|
||||||
expect((<HTMLElement>newlyInsertedElement).id).toEqual("new value");
|
async.done();
|
||||||
async.done();
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should update host properties',
|
||||||
|
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
||||||
|
tcb.createAsync(MyComp).then((tc) => {
|
||||||
|
tc.detectChanges();
|
||||||
|
|
||||||
|
loader.loadNextToLocation(DynamicallyLoadedWithHostProps,
|
||||||
|
tc.componentInstance.viewContainerRef)
|
||||||
|
.then(ref => {
|
||||||
|
ref.instance.id = "new value";
|
||||||
|
|
||||||
|
tc.detectChanges();
|
||||||
|
|
||||||
|
var newlyInsertedElement = tc.debugElement.childNodes[1].nativeNode;
|
||||||
|
expect((<HTMLElement>newlyInsertedElement).id).toEqual("new value");
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
it('should leave the view tree in a consistent state if hydration fails',
|
it('should leave the view tree in a consistent state if hydration fails',
|
||||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||||
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
||||||
tcb.overrideView(MyComp, new ViewMetadata({
|
tcb.createAsync(MyComp).then((tc: ComponentFixture) => {
|
||||||
template: '<div><location #loc></location></div>',
|
tc.detectChanges();
|
||||||
directives: [Location]
|
PromiseWrapper.catchError(
|
||||||
}))
|
loader.loadNextToLocation(DynamicallyLoadedThrows,
|
||||||
.createAsync(MyComp)
|
tc.componentInstance.viewContainerRef),
|
||||||
.then((tc: ComponentFixture) => {
|
(error) => {
|
||||||
PromiseWrapper.catchError(
|
expect(error.message).toContain("ThrownInConstructor");
|
||||||
loader.loadIntoLocation(DynamicallyLoadedThrows, tc.elementRef, 'loc'),
|
expect(() => tc.detectChanges()).not.toThrow();
|
||||||
(error) => {
|
async.done();
|
||||||
expect(error.message).toContain("ThrownInConstructor");
|
return null;
|
||||||
expect(() => tc.detectChanges()).not.toThrow();
|
});
|
||||||
async.done();
|
});
|
||||||
return null;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should throw if the variable does not exist',
|
|
||||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
|
||||||
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
|
||||||
tcb.overrideView(
|
|
||||||
MyComp,
|
|
||||||
new ViewMetadata(
|
|
||||||
{template: '<location #loc></location>', directives: [Location]}))
|
|
||||||
.createAsync(MyComp)
|
|
||||||
.then((tc) => {
|
|
||||||
expect(() => loader.loadIntoLocation(DynamicallyLoadedWithHostProps,
|
|
||||||
tc.elementRef, 'someUnknownVariable'))
|
|
||||||
.toThrowError('Could not find variable someUnknownVariable');
|
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should allow to pass projectable nodes',
|
it('should allow to pass projectable nodes',
|
||||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||||
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
||||||
tcb.overrideView(MyComp,
|
tcb.createAsync(MyComp).then((tc) => {
|
||||||
new ViewMetadata({template: '<div #loc></div>', directives: []}))
|
tc.detectChanges();
|
||||||
.createAsync(MyComp)
|
loader.loadNextToLocation(DynamicallyLoadedWithNgContent,
|
||||||
.then((tc) => {
|
tc.componentInstance.viewContainerRef, null,
|
||||||
loader.loadIntoLocation(DynamicallyLoadedWithNgContent, tc.elementRef,
|
[[DOM.createTextNode('hello')]])
|
||||||
'loc', null, [[DOM.createTextNode('hello')]])
|
.then(ref => {
|
||||||
.then(ref => {
|
tc.detectChanges();
|
||||||
tc.detectChanges();
|
var newlyInsertedElement = tc.debugElement.childNodes[1].nativeNode;
|
||||||
expect(tc.nativeElement).toHaveText('dynamic(hello)');
|
expect(newlyInsertedElement).toHaveText('dynamic(hello)');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should not throw if not enough projectable nodes are passed in',
|
it('should not throw if not enough projectable nodes are passed in',
|
||||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
||||||
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
||||||
tcb.overrideView(MyComp,
|
tcb.createAsync(MyComp).then((tc) => {
|
||||||
new ViewMetadata({template: '<div #loc></div>', directives: []}))
|
tc.detectChanges();
|
||||||
.createAsync(MyComp)
|
loader.loadNextToLocation(DynamicallyLoadedWithNgContent,
|
||||||
.then((tc) => {
|
tc.componentInstance.viewContainerRef, null, [])
|
||||||
loader.loadIntoLocation(DynamicallyLoadedWithNgContent, tc.elementRef,
|
.then((_) => { async.done(); });
|
||||||
'loc', null, [])
|
});
|
||||||
.then((_) => { async.done(); });
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("loading next to a location", () => {
|
|
||||||
it('should work',
|
|
||||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
|
||||||
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
|
||||||
tcb.overrideView(MyComp, new ViewMetadata({
|
|
||||||
template: '<div><location #loc></location></div>',
|
|
||||||
directives: [Location]
|
|
||||||
}))
|
|
||||||
.createAsync(MyComp)
|
|
||||||
.then((tc) => {
|
|
||||||
loader.loadNextToLocation(DynamicallyLoaded, tc.elementRef)
|
|
||||||
.then(ref => {
|
|
||||||
expect(tc.debugElement.nativeElement).toHaveText("Location;");
|
|
||||||
expect(DOM.nextSibling(tc.debugElement.nativeElement))
|
|
||||||
.toHaveText('DynamicallyLoaded;');
|
|
||||||
|
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should return a disposable component ref',
|
|
||||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
|
||||||
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
|
||||||
tcb.overrideView(MyComp, new ViewMetadata({
|
|
||||||
template: '<div><location #loc></location></div>',
|
|
||||||
directives: [Location]
|
|
||||||
}))
|
|
||||||
.
|
|
||||||
|
|
||||||
createAsync(MyComp)
|
|
||||||
.then((tc) => {
|
|
||||||
loader.loadNextToLocation(DynamicallyLoaded, tc.elementRef)
|
|
||||||
.then(ref => {
|
|
||||||
loader.loadNextToLocation(DynamicallyLoaded2, tc.elementRef)
|
|
||||||
.then(ref2 => {
|
|
||||||
var firstSibling =
|
|
||||||
DOM.nextSibling(tc.debugElement.nativeElement);
|
|
||||||
var secondSibling = DOM.nextSibling(firstSibling);
|
|
||||||
expect(tc.debugElement.nativeElement).toHaveText("Location;");
|
|
||||||
expect(firstSibling).toHaveText("DynamicallyLoaded;");
|
|
||||||
expect(secondSibling).toHaveText("DynamicallyLoaded2;");
|
|
||||||
|
|
||||||
ref2.destroy();
|
|
||||||
|
|
||||||
firstSibling = DOM.nextSibling(tc.debugElement.nativeElement);
|
|
||||||
secondSibling = DOM.nextSibling(firstSibling);
|
|
||||||
expect(secondSibling).toBeNull();
|
|
||||||
|
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should update host properties',
|
|
||||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
|
||||||
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
|
||||||
tcb.overrideView(MyComp, new ViewMetadata({
|
|
||||||
template: '<div><location #loc></location></div>',
|
|
||||||
directives: [Location]
|
|
||||||
}))
|
|
||||||
|
|
||||||
.createAsync(MyComp)
|
|
||||||
.then((tc) => {
|
|
||||||
|
|
||||||
loader.loadNextToLocation(DynamicallyLoadedWithHostProps, tc.elementRef)
|
|
||||||
.then(ref => {
|
|
||||||
ref.instance.id = "new value";
|
|
||||||
|
|
||||||
tc.detectChanges();
|
|
||||||
|
|
||||||
var newlyInsertedElement =
|
|
||||||
DOM.nextSibling(tc.debugElement.nativeElement);
|
|
||||||
expect((<HTMLElement>newlyInsertedElement).id).toEqual("new value");
|
|
||||||
|
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should allow to pass projectable nodes',
|
|
||||||
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
|
|
||||||
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
|
|
||||||
tcb.overrideView(MyComp, new ViewMetadata({template: '', directives: [Location]}))
|
|
||||||
.createAsync(MyComp)
|
|
||||||
.then((tc) => {
|
|
||||||
loader.loadNextToLocation(DynamicallyLoadedWithNgContent, tc.elementRef,
|
|
||||||
null, [[DOM.createTextNode('hello')]])
|
|
||||||
.then(ref => {
|
|
||||||
tc.detectChanges();
|
|
||||||
var newlyInsertedElement =
|
|
||||||
DOM.nextSibling(tc.debugElement.nativeElement);
|
|
||||||
expect(newlyInsertedElement).toHaveText('dynamic(hello)');
|
|
||||||
async.done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -362,27 +208,6 @@ class ChildComp {
|
||||||
constructor(public elementRef: ElementRef) { this.ctxProp = 'hello'; }
|
constructor(public elementRef: ElementRef) { this.ctxProp = 'hello'; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class DynamicallyCreatedComponentService {}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'hello-cmp',
|
|
||||||
viewProviders: [DynamicallyCreatedComponentService],
|
|
||||||
template: "{{greeting}}"
|
|
||||||
})
|
|
||||||
class DynamicallyCreatedCmp implements OnDestroy {
|
|
||||||
greeting: string;
|
|
||||||
dynamicallyCreatedComponentService: DynamicallyCreatedComponentService;
|
|
||||||
destroyed: boolean = false;
|
|
||||||
|
|
||||||
constructor(a: DynamicallyCreatedComponentService) {
|
|
||||||
this.greeting = "hello";
|
|
||||||
this.dynamicallyCreatedComponentService = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy() { this.destroyed = true; }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({selector: 'dummy', template: "DynamicallyLoaded;"})
|
@Component({selector: 'dummy', template: "DynamicallyLoaded;"})
|
||||||
class DynamicallyLoaded {
|
class DynamicallyLoaded {
|
||||||
}
|
}
|
||||||
|
@ -410,16 +235,11 @@ class DynamicallyLoadedWithNgContent {
|
||||||
constructor() { this.id = "default"; }
|
constructor() { this.id = "default"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({selector: 'location', template: "Location;"})
|
@Component({selector: 'my-comp', directives: [], template: '<div #loc></div>'})
|
||||||
class Location {
|
|
||||||
elementRef: ElementRef;
|
|
||||||
|
|
||||||
constructor(elementRef: ElementRef) { this.elementRef = elementRef; }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({selector: 'my-comp', directives: []})
|
|
||||||
class MyComp {
|
class MyComp {
|
||||||
ctxBoolProp: boolean;
|
ctxBoolProp: boolean;
|
||||||
|
|
||||||
|
@ViewChild('loc', {read: ViewContainerRef}) viewContainerRef: ViewContainerRef;
|
||||||
|
|
||||||
constructor() { this.ctxBoolProp = false; }
|
constructor() { this.ctxBoolProp = false; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -286,6 +286,99 @@ export function main() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('read a different token', () => {
|
||||||
|
it('should contain all content children',
|
||||||
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
|
var template =
|
||||||
|
'<needs-content-children-read #q text="ca"><div #q text="cb"></div></needs-content-children-read>';
|
||||||
|
|
||||||
|
tcb.overrideTemplate(MyComp, template)
|
||||||
|
.createAsync(MyComp)
|
||||||
|
.then((view) => {
|
||||||
|
view.detectChanges();
|
||||||
|
|
||||||
|
var comp: NeedsContentChildrenWithRead =
|
||||||
|
view.debugElement.children[0].inject(NeedsContentChildrenWithRead);
|
||||||
|
expect(comp.textDirChildren.map(textDirective => textDirective.text))
|
||||||
|
.toEqual(['ca', 'cb']);
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should contain the first content child',
|
||||||
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
|
var template =
|
||||||
|
'<needs-content-child-read><div #q text="ca"></div></needs-content-child-read>';
|
||||||
|
|
||||||
|
tcb.overrideTemplate(MyComp, template)
|
||||||
|
.createAsync(MyComp)
|
||||||
|
.then((view) => {
|
||||||
|
view.detectChanges();
|
||||||
|
|
||||||
|
var comp: NeedsContentChildWithRead =
|
||||||
|
view.debugElement.children[0].inject(NeedsContentChildWithRead);
|
||||||
|
expect(comp.textDirChild.text).toEqual('ca');
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should contain the first view child',
|
||||||
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
|
var template = '<needs-view-child-read></needs-view-child-read>';
|
||||||
|
|
||||||
|
tcb.overrideTemplate(MyComp, template)
|
||||||
|
.createAsync(MyComp)
|
||||||
|
.then((view) => {
|
||||||
|
view.detectChanges();
|
||||||
|
|
||||||
|
var comp: NeedsViewChildWithRead =
|
||||||
|
view.debugElement.children[0].inject(NeedsViewChildWithRead);
|
||||||
|
expect(comp.textDirChild.text).toEqual('va');
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should contain all child directives in the view',
|
||||||
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
|
var template = '<needs-view-children-read></needs-view-children-read>';
|
||||||
|
|
||||||
|
tcb.overrideTemplate(MyComp, template)
|
||||||
|
.createAsync(MyComp)
|
||||||
|
.then((view) => {
|
||||||
|
view.detectChanges();
|
||||||
|
|
||||||
|
var comp: NeedsViewChildrenWithRead =
|
||||||
|
view.debugElement.children[0].inject(NeedsViewChildrenWithRead);
|
||||||
|
expect(comp.textDirChildren.map(textDirective => textDirective.text))
|
||||||
|
.toEqual(['va', 'vb']);
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should support reading a ViewContainer',
|
||||||
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
|
var template =
|
||||||
|
'<needs-viewcontainer-read><template>hello</template></needs-viewcontainer-read>';
|
||||||
|
|
||||||
|
tcb.overrideTemplate(MyComp, template)
|
||||||
|
.createAsync(MyComp)
|
||||||
|
.then((view) => {
|
||||||
|
view.detectChanges();
|
||||||
|
|
||||||
|
var comp: NeedsViewContainerWithRead =
|
||||||
|
view.debugElement.children[0].inject(NeedsViewContainerWithRead);
|
||||||
|
comp.createView();
|
||||||
|
expect(view.debugElement.children[0].nativeElement).toHaveText('hello');
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
describe("changes", () => {
|
describe("changes", () => {
|
||||||
it('should notify query on change',
|
it('should notify query on change',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
|
@ -923,6 +1016,47 @@ class NeedsTpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component({selector: 'needs-content-children-read', template: ''})
|
||||||
|
class NeedsContentChildrenWithRead {
|
||||||
|
@ContentChildren('q', {read: TextDirective}) textDirChildren: QueryList<TextDirective>;
|
||||||
|
@ContentChildren('nonExisting', {read: TextDirective}) nonExistingVar: QueryList<TextDirective>;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({selector: 'needs-content-child-read', template: ''})
|
||||||
|
class NeedsContentChildWithRead {
|
||||||
|
@ContentChild('q', {read: TextDirective}) textDirChild: TextDirective;
|
||||||
|
@ContentChild('nonExisting', {read: TextDirective}) nonExistingVar: TextDirective;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'needs-view-children-read',
|
||||||
|
template: '<div #q text="va"></div><div #q text="vb"></div>',
|
||||||
|
directives: [TextDirective]
|
||||||
|
})
|
||||||
|
class NeedsViewChildrenWithRead {
|
||||||
|
@ViewChildren('q', {read: TextDirective}) textDirChildren: QueryList<TextDirective>;
|
||||||
|
@ViewChildren('nonExisting', {read: TextDirective}) nonExistingVar: QueryList<TextDirective>;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'needs-view-child-read',
|
||||||
|
template: '<div #q text="va"></div>',
|
||||||
|
directives: [TextDirective]
|
||||||
|
})
|
||||||
|
class NeedsViewChildWithRead {
|
||||||
|
@ViewChild('q', {read: TextDirective}) textDirChild: TextDirective;
|
||||||
|
@ViewChild('nonExisting', {read: TextDirective}) nonExistingVar: TextDirective;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({selector: 'needs-viewcontainer-read', template: '<div #q></div>'})
|
||||||
|
class NeedsViewContainerWithRead {
|
||||||
|
@ViewChild('q', {read: ViewContainerRef}) vc: ViewContainerRef;
|
||||||
|
@ViewChild('nonExisting', {read: ViewContainerRef}) nonExistingVar: ViewContainerRef;
|
||||||
|
@ContentChild(TemplateRef) template: TemplateRef;
|
||||||
|
|
||||||
|
createView() { this.vc.createEmbeddedView(this.template); }
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-comp',
|
selector: 'my-comp',
|
||||||
directives: [
|
directives: [
|
||||||
|
@ -946,7 +1080,12 @@ class NeedsTpl {
|
||||||
InertDirective,
|
InertDirective,
|
||||||
NgIf,
|
NgIf,
|
||||||
NgFor,
|
NgFor,
|
||||||
NeedsFourQueries
|
NeedsFourQueries,
|
||||||
|
NeedsContentChildrenWithRead,
|
||||||
|
NeedsContentChildWithRead,
|
||||||
|
NeedsViewChildrenWithRead,
|
||||||
|
NeedsViewChildWithRead,
|
||||||
|
NeedsViewContainerWithRead
|
||||||
],
|
],
|
||||||
template: ''
|
template: ''
|
||||||
})
|
})
|
||||||
|
|
|
@ -604,7 +604,7 @@ export function main() {
|
||||||
it("should inject TemplateRef", fakeAsync(() => {
|
it("should inject TemplateRef", fakeAsync(() => {
|
||||||
var el = createComp('<template needsViewContainerRef needsTemplateRef></template>', tcb);
|
var el = createComp('<template needsViewContainerRef needsTemplateRef></template>', tcb);
|
||||||
expect(el.childNodes[0].inject(NeedsTemplateRef).templateRef.elementRef)
|
expect(el.childNodes[0].inject(NeedsTemplateRef).templateRef.elementRef)
|
||||||
.toBe(el.childNodes[0].inject(NeedsViewContainerRef).viewContainer.element);
|
.toEqual(el.childNodes[0].inject(NeedsViewContainerRef).viewContainer.element);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("should throw if there is no TemplateRef", fakeAsync(() => {
|
it("should throw if there is no TemplateRef", fakeAsync(() => {
|
||||||
|
|
|
@ -145,7 +145,6 @@ var NG_CORE = [
|
||||||
'APP_ID',
|
'APP_ID',
|
||||||
'AngularEntrypoint:dart',
|
'AngularEntrypoint:dart',
|
||||||
'AbstractProviderError',
|
'AbstractProviderError',
|
||||||
'AppViewManager',
|
|
||||||
'ApplicationRef',
|
'ApplicationRef',
|
||||||
'APPLICATION_COMMON_PROVIDERS',
|
'APPLICATION_COMMON_PROVIDERS',
|
||||||
'Attribute',
|
'Attribute',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {Component, ComponentRef} from 'angular2/core';
|
import {Component, ComponentRef, ViewContainerRef, ViewChild} from 'angular2/core';
|
||||||
import {
|
import {
|
||||||
AsyncRoute,
|
AsyncRoute,
|
||||||
Route,
|
Route,
|
||||||
|
@ -11,7 +11,6 @@ import {
|
||||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||||
import {isPresent} from 'angular2/src/facade/lang';
|
import {isPresent} from 'angular2/src/facade/lang';
|
||||||
import {DynamicComponentLoader} from 'angular2/src/core/linker/dynamic_component_loader';
|
import {DynamicComponentLoader} from 'angular2/src/core/linker/dynamic_component_loader';
|
||||||
import {ElementRef} from 'angular2/src/core/linker/element_ref';
|
|
||||||
|
|
||||||
@Component({selector: 'goodbye-cmp', template: `{{farewell}}`})
|
@Component({selector: 'goodbye-cmp', template: `{{farewell}}`})
|
||||||
export class GoodbyeCmp {
|
export class GoodbyeCmp {
|
||||||
|
@ -144,16 +143,17 @@ export class RedirectToParentCmp {
|
||||||
@RouteConfig([new Route({path: '/', component: HelloCmp})])
|
@RouteConfig([new Route({path: '/', component: HelloCmp})])
|
||||||
export class DynamicLoaderCmp {
|
export class DynamicLoaderCmp {
|
||||||
private _componentRef: ComponentRef = null;
|
private _componentRef: ComponentRef = null;
|
||||||
constructor(private _dynamicComponentLoader: DynamicComponentLoader,
|
@ViewChild('viewport', {read: ViewContainerRef}) private _viewport: ViewContainerRef;
|
||||||
private _elementRef: ElementRef) {}
|
|
||||||
|
constructor(private _dynamicComponentLoader: DynamicComponentLoader) {}
|
||||||
|
|
||||||
onSomeAction(): Promise<any> {
|
onSomeAction(): Promise<any> {
|
||||||
if (isPresent(this._componentRef)) {
|
if (isPresent(this._componentRef)) {
|
||||||
this._componentRef.destroy();
|
this._componentRef.destroy();
|
||||||
this._componentRef = null;
|
this._componentRef = null;
|
||||||
}
|
}
|
||||||
return this._dynamicComponentLoader.loadIntoLocation(DynamicallyLoadedComponent,
|
return this._dynamicComponentLoader.loadNextToLocation(DynamicallyLoadedComponent,
|
||||||
this._elementRef, 'viewport')
|
this._viewport)
|
||||||
.then((cmp) => { this._componentRef = cmp; });
|
.then((cmp) => { this._componentRef = cmp; });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,8 @@ import {
|
||||||
ViewMetadata,
|
ViewMetadata,
|
||||||
Component,
|
Component,
|
||||||
Injectable,
|
Injectable,
|
||||||
ElementRef
|
ElementRef,
|
||||||
|
ComponentRef
|
||||||
} from 'angular2/core';
|
} from 'angular2/core';
|
||||||
import {NgIf} from 'angular2/common';
|
import {NgIf} from 'angular2/common';
|
||||||
import {WebWorkerRootRenderer} from "angular2/src/web_workers/worker/renderer";
|
import {WebWorkerRootRenderer} from "angular2/src/web_workers/worker/renderer";
|
||||||
|
@ -119,8 +120,8 @@ export function main() {
|
||||||
return uiRenderStore.deserialize(id);
|
return uiRenderStore.deserialize(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRenderer(elementRef: ElementRef) {
|
function getRenderer(componentRef: ComponentRef) {
|
||||||
return (<any>elementRef).internalElement.parentView.renderer;
|
return (<any>componentRef.hostView).internalView.renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should update text nodes',
|
it('should update text nodes',
|
||||||
|
@ -145,8 +146,8 @@ export function main() {
|
||||||
{template: '<input [title]="y" style="position:absolute">'}))
|
{template: '<input [title]="y" style="position:absolute">'}))
|
||||||
.createAsync(MyComp)
|
.createAsync(MyComp)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
var checkSetters = (componentElRef, workerEl) => {
|
var checkSetters = (componentRef, workerEl) => {
|
||||||
var renderer = getRenderer(componentElRef);
|
var renderer = getRenderer(componentRef);
|
||||||
var el = getRenderElement(workerEl);
|
var el = getRenderElement(workerEl);
|
||||||
renderer.setElementProperty(workerEl, 'tabIndex', 1);
|
renderer.setElementProperty(workerEl, 'tabIndex', 1);
|
||||||
expect((<HTMLInputElement>el).tabIndex).toEqual(1);
|
expect((<HTMLInputElement>el).tabIndex).toEqual(1);
|
||||||
|
@ -166,9 +167,9 @@ export function main() {
|
||||||
};
|
};
|
||||||
|
|
||||||
// root element
|
// root element
|
||||||
checkSetters(fixture.elementRef, fixture.debugElement.nativeElement);
|
checkSetters(fixture.componentRef, fixture.debugElement.nativeElement);
|
||||||
// nested elements
|
// nested elements
|
||||||
checkSetters(fixture.elementRef, fixture.debugElement.children[0].nativeElement);
|
checkSetters(fixture.componentRef, fixture.debugElement.children[0].nativeElement);
|
||||||
|
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
@ -220,7 +221,7 @@ export function main() {
|
||||||
.createAsync(MyComp)
|
.createAsync(MyComp)
|
||||||
.then((fixture) => {
|
.then((fixture) => {
|
||||||
var el = fixture.debugElement.children[0];
|
var el = fixture.debugElement.children[0];
|
||||||
getRenderer(fixture.elementRef)
|
getRenderer(fixture.componentRef)
|
||||||
.invokeElementMethod(el.nativeElement, 'setAttribute', ['a', 'b']);
|
.invokeElementMethod(el.nativeElement, 'setAttribute', ['a', 'b']);
|
||||||
|
|
||||||
expect(DOM.getAttribute(getRenderElement(el.nativeElement), 'a')).toEqual('b');
|
expect(DOM.getAttribute(getRenderElement(el.nativeElement), 'a')).toEqual('b');
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {bootstrap} from 'angular2/platform/browser';
|
import {bootstrap} from 'angular2/platform/browser';
|
||||||
import {Component, Directive, DynamicComponentLoader, ElementRef} from 'angular2/core';
|
import {Component, Directive, DynamicComponentLoader, ViewContainerRef} from 'angular2/core';
|
||||||
import {NgIf, NgFor} from 'angular2/common';
|
import {NgIf, NgFor} from 'angular2/common';
|
||||||
import {ApplicationRef} from 'angular2/src/core/application_ref';
|
import {ApplicationRef} from 'angular2/src/core/application_ref';
|
||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||||
|
@ -53,7 +53,7 @@ class DummyDirective {
|
||||||
|
|
||||||
@Directive({selector: 'dynamic-dummy'})
|
@Directive({selector: 'dynamic-dummy'})
|
||||||
class DynamicDummy {
|
class DynamicDummy {
|
||||||
constructor(loader: DynamicComponentLoader, location: ElementRef) {
|
constructor(loader: DynamicComponentLoader, location: ViewContainerRef) {
|
||||||
loader.loadNextToLocation(DummyComponent, location);
|
loader.loadNextToLocation(DummyComponent, location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,6 @@ const CORE = [
|
||||||
'AfterViewChecked.ngAfterViewChecked():any',
|
'AfterViewChecked.ngAfterViewChecked():any',
|
||||||
'AfterViewInit',
|
'AfterViewInit',
|
||||||
'AfterViewInit.ngAfterViewInit():any',
|
'AfterViewInit.ngAfterViewInit():any',
|
||||||
'AppViewManager',
|
|
||||||
'AppViewManager.getNamedElementInComponentView(hostLocation:ElementRef, variableName:string):ElementRef',
|
|
||||||
'AppViewManager.getViewContainer(location:ElementRef):ViewContainerRef',
|
|
||||||
'ApplicationRef',
|
'ApplicationRef',
|
||||||
'ApplicationRef.bootstrap(componentType:Type, providers:Array<Type|Provider|any[]>):Promise<ComponentRef>',
|
'ApplicationRef.bootstrap(componentType:Type, providers:Array<Type|Provider|any[]>):Promise<ComponentRef>',
|
||||||
'ApplicationRef.componentTypes:Type[]',
|
'ApplicationRef.componentTypes:Type[]',
|
||||||
|
@ -104,10 +101,10 @@ const CORE = [
|
||||||
'ConcreteType',
|
'ConcreteType',
|
||||||
'ContentChildMetadataFactory',
|
'ContentChildMetadataFactory',
|
||||||
'ContentChildMetadata',
|
'ContentChildMetadata',
|
||||||
'ContentChildMetadata.constructor(_selector:Type|string)',
|
'ContentChildMetadata.constructor(_selector:Type|string, {read=null}:{read?:any})',
|
||||||
'ContentChildrenMetadataFactory',
|
'ContentChildrenMetadataFactory',
|
||||||
'ContentChildrenMetadata',
|
'ContentChildrenMetadata',
|
||||||
'ContentChildrenMetadata.constructor(_selector:Type|string, {descendants=false}:{descendants?:boolean})',
|
'ContentChildrenMetadata.constructor(_selector:Type|string, {descendants=false,read=null}:{descendants?:boolean, read?:any})',
|
||||||
'CyclicDependencyError',
|
'CyclicDependencyError',
|
||||||
'CyclicDependencyError.constructor(injector:Injector, key:Key)',
|
'CyclicDependencyError.constructor(injector:Injector, key:Key)',
|
||||||
'DebugNode',
|
'DebugNode',
|
||||||
|
@ -161,10 +158,10 @@ const CORE = [
|
||||||
'DoCheck.ngDoCheck():any',
|
'DoCheck.ngDoCheck():any',
|
||||||
'DynamicComponentLoader',
|
'DynamicComponentLoader',
|
||||||
'DynamicComponentLoader.loadAsRoot(type:Type, overrideSelectorOrNode:string, injector:Injector, onDispose:() => void, projectableNodes:any[][]):Promise<ComponentRef>',
|
'DynamicComponentLoader.loadAsRoot(type:Type, overrideSelectorOrNode:string, injector:Injector, onDispose:() => void, projectableNodes:any[][]):Promise<ComponentRef>',
|
||||||
'DynamicComponentLoader.loadIntoLocation(type:Type, hostLocation:ElementRef, anchorName:string, providers:ResolvedProvider[], projectableNodes:any[][]):Promise<ComponentRef>',
|
'DynamicComponentLoader.loadNextToLocation(type:Type, location:ViewContainerRef, providers:ResolvedProvider[], projectableNodes:any[][]):Promise<ComponentRef>',
|
||||||
'DynamicComponentLoader.loadNextToLocation(type:Type, location:ElementRef, providers:ResolvedProvider[], projectableNodes:any[][]):Promise<ComponentRef>',
|
|
||||||
'ElementRef',
|
'ElementRef',
|
||||||
'ElementRef.nativeElement:any',
|
'ElementRef.nativeElement:any',
|
||||||
|
'ElementRef.constructor(nativeElement:any)',
|
||||||
'EmbeddedViewRef',
|
'EmbeddedViewRef',
|
||||||
'EmbeddedViewRef.hasLocal(variableName:string):boolean',
|
'EmbeddedViewRef.hasLocal(variableName:string):boolean',
|
||||||
'EmbeddedViewRef.rootNodes:any[]',
|
'EmbeddedViewRef.rootNodes:any[]',
|
||||||
|
@ -344,7 +341,8 @@ const CORE = [
|
||||||
'QueryList.toString():string',
|
'QueryList.toString():string',
|
||||||
'QueryList<T>',
|
'QueryList<T>',
|
||||||
'QueryMetadata',
|
'QueryMetadata',
|
||||||
'QueryMetadata.constructor(_selector:Type|string, {descendants=false,first=false}:{descendants?:boolean, first?:boolean})',
|
'QueryMetadata.constructor(_selector:Type|string, {descendants=false,first=false,read=null}:{descendants?:boolean, first?:boolean, read?:any})',
|
||||||
|
'QueryMetadata.read:any',
|
||||||
'QueryMetadata.descendants:boolean',
|
'QueryMetadata.descendants:boolean',
|
||||||
'QueryMetadata.first:boolean',
|
'QueryMetadata.first:boolean',
|
||||||
'QueryMetadata.isVarBindingQuery:boolean',
|
'QueryMetadata.isVarBindingQuery:boolean',
|
||||||
|
@ -438,10 +436,10 @@ const CORE = [
|
||||||
'TypeDecorator.annotations:any[]',
|
'TypeDecorator.annotations:any[]',
|
||||||
'ViewChildMetadataFactory',
|
'ViewChildMetadataFactory',
|
||||||
'ViewChildMetadata',
|
'ViewChildMetadata',
|
||||||
'ViewChildMetadata.constructor(_selector:Type|string)',
|
'ViewChildMetadata.constructor(_selector:Type|string, {read=null}:{read?:any})',
|
||||||
'ViewChildrenMetadataFactory',
|
'ViewChildrenMetadataFactory',
|
||||||
'ViewChildrenMetadata',
|
'ViewChildrenMetadata',
|
||||||
'ViewChildrenMetadata.constructor(_selector:Type|string)',
|
'ViewChildrenMetadata.constructor(_selector:Type|string, {read=null}:{read?:any})',
|
||||||
'ViewContainerRef',
|
'ViewContainerRef',
|
||||||
'ViewContainerRef.clear():void',
|
'ViewContainerRef.clear():void',
|
||||||
'ViewContainerRef.createEmbeddedView(templateRef:TemplateRef, index:number):EmbeddedViewRef',
|
'ViewContainerRef.createEmbeddedView(templateRef:TemplateRef, index:number):EmbeddedViewRef',
|
||||||
|
@ -470,7 +468,7 @@ const CORE = [
|
||||||
'ViewMetadata.template:string',
|
'ViewMetadata.template:string',
|
||||||
'ViewMetadata.templateUrl:string',
|
'ViewMetadata.templateUrl:string',
|
||||||
'ViewQueryMetadata',
|
'ViewQueryMetadata',
|
||||||
'ViewQueryMetadata.constructor(_selector:Type|string, {descendants=false,first=false}:{descendants?:boolean, first?:boolean})',
|
'ViewQueryMetadata.constructor(_selector:Type|string, {descendants=false,first=false,read=null}:{descendants?:boolean, first?:boolean, read?:any})',
|
||||||
'ViewQueryMetadata.isViewQuery:any',
|
'ViewQueryMetadata.isViewQuery:any',
|
||||||
'ViewQueryMetadata.toString():string',
|
'ViewQueryMetadata.toString():string',
|
||||||
'ViewRef',
|
'ViewRef',
|
||||||
|
@ -844,12 +842,12 @@ const COMPILER =
|
||||||
'DirectiveAst.constructor(directive:CompileDirectiveMetadata, inputs:BoundDirectivePropertyAst[], hostProperties:BoundElementPropertyAst[], hostEvents:BoundEventAst[], exportAsVars:VariableAst[], sourceSpan:ParseSourceSpan)',
|
'DirectiveAst.constructor(directive:CompileDirectiveMetadata, inputs:BoundDirectivePropertyAst[], hostProperties:BoundElementPropertyAst[], hostEvents:BoundEventAst[], exportAsVars:VariableAst[], sourceSpan:ParseSourceSpan)',
|
||||||
'DirectiveAst.visit(visitor:TemplateAstVisitor, context:any):any',
|
'DirectiveAst.visit(visitor:TemplateAstVisitor, context:any):any',
|
||||||
'ElementAst',
|
'ElementAst',
|
||||||
'ElementAst.constructor(name:string, attrs:AttrAst[], inputs:BoundElementPropertyAst[], outputs:BoundEventAst[], exportAsVars:VariableAst[], directives:DirectiveAst[], providers:ProviderAst[], children:TemplateAst[], ngContentIndex:number, sourceSpan:ParseSourceSpan)',
|
'ElementAst.constructor(name:string, attrs:AttrAst[], inputs:BoundElementPropertyAst[], outputs:BoundEventAst[], exportAsVars:VariableAst[], directives:DirectiveAst[], providers:ProviderAst[], hasViewContainer:boolean, children:TemplateAst[], ngContentIndex:number, sourceSpan:ParseSourceSpan)',
|
||||||
'ElementAst.getComponent():CompileDirectiveMetadata',
|
'ElementAst.getComponent():CompileDirectiveMetadata',
|
||||||
'ElementAst.isBound():boolean',
|
'ElementAst.isBound():boolean',
|
||||||
'ElementAst.visit(visitor:TemplateAstVisitor, context:any):any',
|
'ElementAst.visit(visitor:TemplateAstVisitor, context:any):any',
|
||||||
'EmbeddedTemplateAst',
|
'EmbeddedTemplateAst',
|
||||||
'EmbeddedTemplateAst.constructor(attrs:AttrAst[], outputs:BoundEventAst[], vars:VariableAst[], directives:DirectiveAst[], providers:ProviderAst[], children:TemplateAst[], ngContentIndex:number, sourceSpan:ParseSourceSpan)',
|
'EmbeddedTemplateAst.constructor(attrs:AttrAst[], outputs:BoundEventAst[], vars:VariableAst[], directives:DirectiveAst[], providers:ProviderAst[], hasViewContainer:boolean, children:TemplateAst[], ngContentIndex:number, sourceSpan:ParseSourceSpan)',
|
||||||
'EmbeddedTemplateAst.visit(visitor:TemplateAstVisitor, context:any):any',
|
'EmbeddedTemplateAst.visit(visitor:TemplateAstVisitor, context:any):any',
|
||||||
'NgContentAst',
|
'NgContentAst',
|
||||||
'NgContentAst.constructor(index:number, ngContentIndex:number, sourceSpan:ParseSourceSpan)',
|
'NgContentAst.constructor(index:number, ngContentIndex:number, sourceSpan:ParseSourceSpan)',
|
||||||
|
@ -958,7 +956,8 @@ const COMPILER =
|
||||||
'CompileProviderMetadata.useFactory:CompileFactoryMetadata',
|
'CompileProviderMetadata.useFactory:CompileFactoryMetadata',
|
||||||
'CompileProviderMetadata.useValue:any',
|
'CompileProviderMetadata.useValue:any',
|
||||||
'CompileQueryMetadata',
|
'CompileQueryMetadata',
|
||||||
'CompileQueryMetadata.constructor({selectors,descendants,first,propertyName}:{selectors?:Array<CompileTokenMetadata>, descendants?:boolean, first?:boolean, propertyName?:string})',
|
'CompileQueryMetadata.constructor({selectors,descendants,first,propertyName,read}:{selectors?:Array<CompileTokenMetadata>, descendants?:boolean, first?:boolean, propertyName?:string, read?:CompileTokenMetadata})',
|
||||||
|
'CompileQueryMetadata.read:CompileTokenMetadata',
|
||||||
'CompileQueryMetadata.descendants:boolean',
|
'CompileQueryMetadata.descendants:boolean',
|
||||||
'CompileQueryMetadata.first:boolean',
|
'CompileQueryMetadata.first:boolean',
|
||||||
'CompileQueryMetadata.fromJson(data:{[key:string]:any}):CompileQueryMetadata',
|
'CompileQueryMetadata.fromJson(data:{[key:string]:any}):CompileQueryMetadata',
|
||||||
|
|
Loading…
Reference in New Issue