refactor(view_compiler): codegen DI and Queries

BREAKING CHANGE:
- Renderer:
  * renderComponent method is removed form `Renderer`, only present on `RootRenderer`
  * Renderer.setDebugInfo is removed. Renderer.createElement / createText / createTemplateAnchor
    now take the DebugInfo directly.
- Query semantics:
  * Queries don't work with dynamically loaded components.
  * e.g. for router-outlet: loaded components can't be queries via @ViewQuery,
    but router-outlet emits an event `activate` now that emits the activated component
- Exception classes and the context inside changed (renamed fields)
- DebugElement.attributes is an Object and not a Map in JS any more
- ChangeDetectorGenConfig was renamed into CompilerConfig
- AppViewManager.createEmbeddedViewInContainer / AppViewManager.createHostViewInContainer
  are removed, use the methods in ViewContainerRef instead
- Change detection order changed:
  * 1. dirty check component inputs
  * 2. dirty check content children
  * 3. update render nodes

Closes #6301
Closes #6567
This commit is contained in:
Tobias Bosch
2016-01-06 14:13:44 -08:00
parent 45f09ba686
commit 2b34c88b69
312 changed files with 14271 additions and 16566 deletions

View File

@ -42,8 +42,7 @@ import {
ServiceMessageBrokerFactory,
ServiceMessageBrokerFactory_
} from 'angular2/src/web_workers/shared/service_message_broker';
import {ChangeDetectorGenConfig} from 'angular2/src/core/change_detection/change_detection';
import {ElementRef_} from 'angular2/src/core/linker/element_ref';
import {CompilerConfig} from 'angular2/compiler';
import {
TEST_BROWSER_PLATFORM_PROVIDERS,
TEST_BROWSER_APPLICATION_PROVIDERS
@ -102,8 +101,7 @@ export function main() {
workerRenderStore = new RenderStore();
return [
Serializer,
provide(ChangeDetectorGenConfig,
{useValue: new ChangeDetectorGenConfig(true, true, false)}),
provide(CompilerConfig, {useValue: new CompilerConfig(true, true, false)}),
provide(RenderStore, {useValue: workerRenderStore}),
provide(RootRenderer,
{
@ -116,8 +114,8 @@ export function main() {
];
});
function getRenderElement(elementRef: ElementRef) {
var id = workerRenderStore.serialize(elementRef.nativeElement);
function getRenderElement(workerEl: any) {
var id = workerRenderStore.serialize(workerEl);
return uiRenderStore.deserialize(id);
}
@ -130,7 +128,7 @@ export function main() {
tcb.overrideView(MyComp, new ViewMetadata({template: '<div>{{ctxProp}}</div>'}))
.createAsync(MyComp)
.then((fixture) => {
var renderEl = getRenderElement(fixture.elementRef);
var renderEl = getRenderElement(fixture.debugElement.nativeElement);
expect(renderEl).toHaveText('');
fixture.debugElement.componentInstance.ctxProp = 'Hello World!';
@ -147,32 +145,30 @@ export function main() {
{template: '<input [title]="y" style="position:absolute">'}))
.createAsync(MyComp)
.then((fixture) => {
var checkSetters = (elr) => {
var renderer = getRenderer(elr);
var el = getRenderElement(elr);
renderer.setElementProperty(elr.nativeElement, 'tabIndex', 1);
var checkSetters = (componentElRef, workerEl) => {
var renderer = getRenderer(componentElRef);
var el = getRenderElement(workerEl);
renderer.setElementProperty(workerEl, 'tabIndex', 1);
expect((<HTMLInputElement>el).tabIndex).toEqual(1);
renderer.setElementClass(elr.nativeElement, 'a', true);
renderer.setElementClass(workerEl, 'a', true);
expect(DOM.hasClass(el, 'a')).toBe(true);
renderer.setElementClass(elr.nativeElement, 'a', false);
renderer.setElementClass(workerEl, 'a', false);
expect(DOM.hasClass(el, 'a')).toBe(false);
renderer.setElementStyle(elr.nativeElement, 'width', '10px');
renderer.setElementStyle(workerEl, 'width', '10px');
expect(DOM.getStyle(el, 'width')).toEqual('10px');
renderer.setElementStyle(elr.nativeElement, 'width', null);
renderer.setElementStyle(workerEl, 'width', null);
expect(DOM.getStyle(el, 'width')).toEqual('');
renderer.setElementAttribute(elr.nativeElement, 'someattr', 'someValue');
renderer.setElementAttribute(workerEl, 'someattr', 'someValue');
expect(DOM.getAttribute(el, 'someattr')).toEqual('someValue');
};
// root element
checkSetters(fixture.elementRef);
checkSetters(fixture.elementRef, fixture.debugElement.nativeElement);
// nested elements
checkSetters((<ElementRef_>fixture.elementRef)
.internalElement.componentView.appElements[0]
.ref);
checkSetters(fixture.elementRef, fixture.debugElement.children[0].nativeElement);
async.done();
});
@ -187,7 +183,7 @@ export function main() {
.then((fixture) => {
(<MyComp>fixture.debugElement.componentInstance).ctxBoolProp = true;
fixture.detectChanges();
var el = getRenderElement(fixture.elementRef);
var el = getRenderElement(fixture.debugElement.nativeElement);
expect(DOM.getInnerHTML(el)).toContain('"ng-reflect-ng-if": "true"');
async.done();
});
@ -202,7 +198,7 @@ export function main() {
.createAsync(MyComp)
.then((fixture) => {
var rootEl = getRenderElement(fixture.elementRef);
var rootEl = getRenderElement(fixture.debugElement.nativeElement);
expect(rootEl).toHaveText('');
fixture.debugElement.componentInstance.ctxBoolProp = true;
@ -223,13 +219,11 @@ export function main() {
tcb.overrideView(MyComp, new ViewMetadata({template: '<input [title]="y">'}))
.createAsync(MyComp)
.then((fixture) => {
var elRef = (<ElementRef_>fixture.elementRef)
.internalElement.componentView.appElements[0]
.ref;
getRenderer(elRef)
.invokeElementMethod(elRef.nativeElement, 'setAttribute', ['a', 'b']);
var el = fixture.debugElement.children[0];
getRenderer(fixture.elementRef)
.invokeElementMethod(el.nativeElement, 'setAttribute', ['a', 'b']);
expect(DOM.getAttribute(getRenderElement(elRef), 'a')).toEqual('b');
expect(DOM.getAttribute(getRenderElement(el.nativeElement), 'a')).toEqual('b');
async.done();
});
}));
@ -240,10 +234,8 @@ export function main() {
new ViewMetadata({template: '<input (change)="ctxNumProp = 1">'}))
.createAsync(MyComp)
.then((fixture) => {
var elRef = (<ElementRef_>fixture.elementRef)
.internalElement.componentView.appElements[0]
.ref;
dispatchEvent(getRenderElement(elRef), 'change');
var el = fixture.debugElement.children[0];
dispatchEvent(getRenderElement(el.nativeElement), 'change');
expect(fixture.componentInstance.ctxNumProp).toBe(1);
fixture.destroy();