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:
@ -16,8 +16,8 @@ import {Injector, provide} from 'angular2/core';
|
||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
|
||||
import {parseRouterLinkExpression} from 'angular2/src/router/directives/router_link_transform';
|
||||
import {Unparser} from '../../core/change_detection/parser/unparser';
|
||||
import {Parser} from 'angular2/src/core/change_detection/parser/parser';
|
||||
import {Unparser} from '../../compiler/expression_parser/unparser';
|
||||
import {Parser} from 'angular2/src/compiler/expression_parser/parser';
|
||||
|
||||
export function main() {
|
||||
function check(parser: Parser, input: string, expectedValue: string) {
|
||||
|
@ -18,7 +18,7 @@ import {bootstrap} from 'angular2/platform/browser';
|
||||
import {Component, Directive} from 'angular2/src/core/metadata';
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
import {Console} from 'angular2/src/core/console';
|
||||
import {provide, ViewChild, AfterViewInit} from 'angular2/core';
|
||||
import {provide} from 'angular2/core';
|
||||
import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
|
||||
import {
|
||||
RouteConfig,
|
||||
@ -214,7 +214,7 @@ export function main() {
|
||||
}));
|
||||
});
|
||||
|
||||
describe('retrieving components loaded via outlet via @ViewChild', () => {
|
||||
describe('activate event on outlet', () => {
|
||||
let tcb: TestComponentBuilder = null;
|
||||
|
||||
beforeEachProviders(() => [provide(ROUTER_PRIMARY_COMPONENT, {useValue: AppCmp})]);
|
||||
@ -224,7 +224,7 @@ export function main() {
|
||||
|
||||
it('should get a reference and pass data to components loaded inside of outlets',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
tcb.createAsync(AppWithViewChildren)
|
||||
tcb.createAsync(AppWithOutletListeners)
|
||||
.then(fixture => {
|
||||
let appInstance = fixture.debugElement.componentInstance;
|
||||
let router = appInstance.router;
|
||||
@ -272,21 +272,26 @@ class AppCmp {
|
||||
selector: 'app-cmp',
|
||||
template: `
|
||||
Hello routing!
|
||||
<router-outlet></router-outlet>
|
||||
<router-outlet name="pony"></router-outlet>`,
|
||||
<router-outlet (activate)="activateHello($event)"></router-outlet>
|
||||
<router-outlet (activate)="activateHello2($event)" name="pony"></router-outlet>`,
|
||||
directives: ROUTER_DIRECTIVES
|
||||
})
|
||||
@RouteConfig([
|
||||
new Route({path: '/rainbow', component: HelloCmp}),
|
||||
new AuxRoute({name: 'pony', path: 'pony', component: Hello2Cmp})
|
||||
])
|
||||
class AppWithViewChildren implements AfterViewInit {
|
||||
@ViewChild(HelloCmp) helloCmp: HelloCmp;
|
||||
@ViewChild(Hello2Cmp) hello2Cmp: Hello2Cmp;
|
||||
class AppWithOutletListeners {
|
||||
helloCmp: HelloCmp;
|
||||
hello2Cmp: Hello2Cmp;
|
||||
|
||||
constructor(public router: Router, public location: LocationStrategy) {}
|
||||
|
||||
ngAfterViewInit() { this.helloCmp.message = 'Ahoy'; }
|
||||
activateHello(cmp: HelloCmp) {
|
||||
this.helloCmp = cmp;
|
||||
this.helloCmp.message = 'Ahoy';
|
||||
}
|
||||
|
||||
activateHello2(cmp: Hello2Cmp) { this.hello2Cmp = cmp; }
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
@ -16,7 +16,7 @@ import {
|
||||
} from 'angular2/testing_internal';
|
||||
|
||||
import {provide, Component, Injector, Inject} from 'angular2/core';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {PromiseWrapper, TimerWrapper} from 'angular2/src/facade/async';
|
||||
|
||||
import {Router, RouterOutlet, RouterLink, RouteParams, RouteData, Location} from 'angular2/router';
|
||||
import {
|
||||
@ -216,6 +216,24 @@ export function main() {
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should fire an event for each activated component',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
compile(tcb, '<router-outlet (activate)="activatedCmp = $event"></router-outlet>')
|
||||
.then((rtc) => {fixture = rtc})
|
||||
.then((_) => rtr.config([new Route({path: '/test', component: HelloCmp})]))
|
||||
.then((_) => rtr.navigateByUrl('/test'))
|
||||
.then((_) => {
|
||||
// Note: need a timeout so that all promises are flushed
|
||||
var completer = PromiseWrapper.completer();
|
||||
TimerWrapper.setTimeout(() => { completer.resolve(null); }, 0);
|
||||
return completer.promise;
|
||||
})
|
||||
.then((_) => {
|
||||
expect(fixture.componentInstance.activatedCmp).toBeAnInstanceOf(HelloCmp);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ import {NumberWrapper} from 'angular2/src/facade/lang';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
import {provide, Component, DirectiveResolver} from 'angular2/core';
|
||||
import {provide, Component} from 'angular2/core';
|
||||
|
||||
import {SpyLocation} from 'angular2/src/mock/location_mock';
|
||||
import {
|
||||
@ -54,7 +54,6 @@ export function main() {
|
||||
|
||||
beforeEachProviders(() => [
|
||||
RouteRegistry,
|
||||
DirectiveResolver,
|
||||
provide(Location, {useClass: SpyLocation}),
|
||||
provide(ROUTER_PRIMARY_COMPONENT, {useValue: MyComp}),
|
||||
provide(Router, {useClass: RootRouter}),
|
||||
|
@ -23,7 +23,6 @@ import {Router, ROUTER_DIRECTIVES, ROUTER_PRIMARY_COMPONENT} from 'angular2/rout
|
||||
import {SpyLocation} from 'angular2/src/mock/location_mock';
|
||||
import {Location} from 'angular2/src/router/location/location';
|
||||
import {RouteRegistry} from 'angular2/src/router/route_registry';
|
||||
import {DirectiveResolver} from 'angular2/src/core/linker/directive_resolver';
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
export {ComponentFixture} from 'angular2/testing_internal';
|
||||
|
||||
@ -39,6 +38,7 @@ export {ComponentFixture} from 'angular2/testing_internal';
|
||||
})
|
||||
export class RootCmp {
|
||||
name: string;
|
||||
activatedCmp: any;
|
||||
}
|
||||
|
||||
export function compile(tcb: TestComponentBuilder,
|
||||
@ -48,7 +48,6 @@ export function compile(tcb: TestComponentBuilder,
|
||||
|
||||
export var TEST_ROUTER_PROVIDERS = [
|
||||
RouteRegistry,
|
||||
DirectiveResolver,
|
||||
provide(Location, {useClass: SpyLocation}),
|
||||
provide(ROUTER_PRIMARY_COMPONENT, {useValue: RootCmp}),
|
||||
provide(Router, {useClass: RootRouter})
|
||||
|
@ -27,7 +27,6 @@ import {
|
||||
Route,
|
||||
Redirect
|
||||
} from 'angular2/src/router/route_config/route_config_decorator';
|
||||
import {DirectiveResolver} from 'angular2/src/core/linker/directive_resolver';
|
||||
|
||||
import {provide} from 'angular2/core';
|
||||
import {RouterOutlet} from 'angular2/src/router/directives/router_outlet';
|
||||
@ -39,7 +38,6 @@ export function main() {
|
||||
|
||||
beforeEachProviders(() => [
|
||||
RouteRegistry,
|
||||
DirectiveResolver,
|
||||
provide(Location, {useClass: SpyLocation}),
|
||||
provide(ROUTER_PRIMARY_COMPONENT, {useValue: AppCmp}),
|
||||
provide(Router, {useClass: RootRouter})
|
||||
|
Reference in New Issue
Block a user