feat(change_detection): implement a change detector generator

This commit is contained in:
vsavkin
2015-01-21 12:05:52 -08:00
parent b78c1252e5
commit 850cf0fef4
31 changed files with 1347 additions and 694 deletions
+15 -8
View File
@@ -4,7 +4,7 @@ import {DOM, Element} from 'facade/dom';
import {Compiler, CompilerCache} from './compiler/compiler';
import {ProtoView} from './compiler/view';
import {Reflector, reflector} from 'reflection/reflection';
import {Parser, Lexer, ChangeDetector} from 'change_detection/change_detection';
import {Parser, Lexer, ChangeDetection, dynamicChangeDetection, jitChangeDetection} from 'change_detection/change_detection';
import {TemplateLoader} from './compiler/template_loader';
import {DirectiveMetadataReader} from './compiler/directive_metadata_reader';
import {DirectiveMetadata} from './compiler/directive_metadata';
@@ -17,7 +17,14 @@ var _rootInjector: Injector;
// Contains everything that is safe to share between applications.
var _rootBindings = [
bind(Reflector).toValue(reflector), Compiler, CompilerCache, TemplateLoader, DirectiveMetadataReader, Parser, Lexer
bind(Reflector).toValue(reflector),
bind(ChangeDetection).toValue(dynamicChangeDetection),
Compiler,
CompilerCache,
TemplateLoader,
DirectiveMetadataReader,
Parser,
Lexer
];
export var appViewToken = new OpaqueToken('AppView');
@@ -45,20 +52,20 @@ function _injectorBindings(appComponentType) {
return element;
}, [appComponentAnnotatedTypeToken, appDocumentToken]),
bind(appViewToken).toAsyncFactory((compiler, injector, appElement,
bind(appViewToken).toAsyncFactory((changeDetection, compiler, injector, appElement,
appComponentAnnotatedType) => {
return compiler.compile(appComponentAnnotatedType.type, null).then(
(protoView) => {
var appProtoView = ProtoView.createRootProtoView(protoView,
appElement, appComponentAnnotatedType);
var appProtoView = ProtoView.createRootProtoView(protoView,
appElement, appComponentAnnotatedType, changeDetection.createProtoChangeDetector('root'));
// The light Dom of the app element is not considered part of
// the angular application. Thus the context and lightDomInjector are
// empty.
var view = appProtoView.instantiate(null);
view.hydrate(injector, null, new Object());
var view = appProtoView.instantiate(null);
view.hydrate(injector, null, new Object());
return view;
});
}, [Compiler, Injector, appElementToken, appComponentAnnotatedTypeToken]),
}, [ChangeDetection, Compiler, Injector, appElementToken, appComponentAnnotatedTypeToken]),
bind(appChangeDetectorToken).toFactory((rootView) => rootView.changeDetector,
[appViewToken]),
+6 -3
View File
@@ -3,7 +3,7 @@ import {Promise, PromiseWrapper} from 'facade/async';
import {List, ListWrapper, MapWrapper} from 'facade/collection';
import {DOM, Element} from 'facade/dom';
import {Parser} from 'change_detection/change_detection';
import {ChangeDetection, Parser} from 'change_detection/change_detection';
import {DirectiveMetadataReader} from './directive_metadata_reader';
import {ProtoView} from './view';
@@ -52,7 +52,10 @@ export class Compiler {
_reader: DirectiveMetadataReader;
_parser:Parser;
_compilerCache:CompilerCache;
constructor(templateLoader:TemplateLoader, reader: DirectiveMetadataReader, parser:Parser, cache:CompilerCache) {
_changeDetection:ChangeDetection;
constructor(changeDetection:ChangeDetection, templateLoader:TemplateLoader, reader: DirectiveMetadataReader, parser:Parser, cache:CompilerCache) {
this._changeDetection = changeDetection;
this._reader = reader;
this._parser = parser;
this._compilerCache = cache;
@@ -60,7 +63,7 @@ export class Compiler {
createSteps(component:DirectiveMetadata):List<CompileStep> {
var dirs = ListWrapper.map(component.componentDirectives, (d) => this._reader.read(d));
return createDefaultSteps(this._parser, component, dirs);
return createDefaultSteps(this._changeDetection, this._parser, component, dirs);
}
compile(component:Type, templateRoot:Element = null):Promise<ProtoView> {
@@ -1,4 +1,4 @@
import {Parser} from 'change_detection/change_detection';
import {ChangeDetection, Parser} from 'change_detection/change_detection';
import {List} from 'facade/collection';
import {PropertyBindingParser} from './property_binding_parser';
@@ -17,8 +17,12 @@ import {stringify} from 'facade/lang';
* Takes in an HTMLElement and produces the ProtoViews,
* ProtoElementInjectors and ElementBinders in the end.
*/
export function createDefaultSteps(parser:Parser, compiledComponent: DirectiveMetadata,
export function createDefaultSteps(
changeDetection:ChangeDetection,
parser:Parser,
compiledComponent: DirectiveMetadata,
directives: List<DirectiveMetadata>) {
var compilationUnit = stringify(compiledComponent.type);
return [
@@ -27,7 +31,7 @@ export function createDefaultSteps(parser:Parser, compiledComponent: DirectiveMe
new DirectiveParser(directives),
new TextInterpolationParser(parser, compilationUnit),
new ElementBindingMarker(),
new ProtoViewBuilder(),
new ProtoViewBuilder(changeDetection),
new ProtoElementInjectorBuilder(),
new ElementBinderBuilder()
];
@@ -2,7 +2,7 @@ import {isPresent, BaseException} from 'facade/lang';
import {ListWrapper, MapWrapper} from 'facade/collection';
import {ProtoView} from '../view';
import {ProtoChangeDetector} from 'change_detection/change_detection';
import {ChangeDetection} from 'change_detection/change_detection';
import {CompileStep} from './compile_step';
import {CompileElement} from './compile_element';
@@ -18,10 +18,16 @@ import {CompileControl} from './compile_control';
* - CompileElement#isViewRoot
*/
export class ProtoViewBuilder extends CompileStep {
changeDetection:ChangeDetection;
constructor(changeDetection:ChangeDetection) {
this.changeDetection = changeDetection;
}
process(parent:CompileElement, current:CompileElement, control:CompileControl) {
var inheritedProtoView = null;
if (current.isViewRoot) {
inheritedProtoView = new ProtoView(current.element, new ProtoChangeDetector());
var protoChangeDetector = this.changeDetection.createProtoChangeDetector('dummy');
inheritedProtoView = new ProtoView(current.element, protoChangeDetector);
if (isPresent(parent)) {
if (isPresent(parent.inheritedElementBinder.nestedProtoView)) {
throw new BaseException('Only one nested view per element is allowed');
+5 -2
View File
@@ -492,9 +492,12 @@ export class ProtoView {
// and the component template is already compiled into protoView.
// Used for bootstrapping.
static createRootProtoView(protoView: ProtoView,
insertionElement, rootComponentAnnotatedType: DirectiveMetadata): ProtoView {
insertionElement, rootComponentAnnotatedType: DirectiveMetadata,
protoChangeDetector:ProtoChangeDetector
): ProtoView {
DOM.addClass(insertionElement, 'ng-binding');
var rootProtoView = new ProtoView(insertionElement, new ProtoChangeDetector());
var rootProtoView = new ProtoView(insertionElement, protoChangeDetector);
rootProtoView.instantiateInPlace = true;
var binder = rootProtoView.bindElement(
new ProtoElementInjector(null, 0, [rootComponentAnnotatedType.type], true));
+2 -2
View File
@@ -12,7 +12,7 @@ import {CompileElement} from 'core/compiler/pipeline/compile_element';
import {CompileStep} from 'core/compiler/pipeline/compile_step'
import {CompileControl} from 'core/compiler/pipeline/compile_control';
import {Lexer, Parser} from 'change_detection/change_detection';
import {Lexer, Parser, dynamicChangeDetection} from 'change_detection/change_detection';
export function main() {
describe('compiler', function() {
@@ -134,7 +134,7 @@ class RecursiveComponent {}
class TestableCompiler extends Compiler {
steps:List;
constructor(reader:DirectiveMetadataReader, steps:List<CompileStep>) {
super(null, reader, new Parser(new Lexer()), new CompilerCache());
super(dynamicChangeDetection, null, reader, new Parser(new Lexer()), new CompilerCache());
this.steps = steps;
}
createSteps(component):List<CompileStep> {
@@ -3,7 +3,7 @@ import {describe, xit, it, expect, beforeEach, ddescribe, iit, el} from 'test_li
import {DOM} from 'facade/dom';
import {Injector} from 'di/di';
import {Lexer, Parser, ChangeDetector} from 'change_detection/change_detection';
import {Lexer, Parser, ChangeDetector, dynamicChangeDetection} from 'change_detection/change_detection';
import {Compiler, CompilerCache} from 'core/compiler/compiler';
import {DirectiveMetadataReader} from 'core/compiler/directive_metadata_reader';
@@ -20,7 +20,8 @@ export function main() {
var compiler;
beforeEach( () => {
compiler = new Compiler(null, new DirectiveMetadataReader(), new Parser(new Lexer()), new CompilerCache());
compiler = new Compiler(dynamicChangeDetection, null, new DirectiveMetadataReader(),
new Parser(new Lexer()), new CompilerCache());
});
describe('react to record changes', function() {
@@ -16,7 +16,8 @@ import {ProtoView, ElementPropertyMemento, DirectivePropertyMemento} from 'core/
import {ProtoElementInjector} from 'core/compiler/element_injector';
import {DirectiveMetadataReader} from 'core/compiler/directive_metadata_reader';
import {ChangeDetector, Lexer, Parser, ProtoChangeDetector} from 'change_detection/change_detection';
import {ChangeDetector, Lexer, Parser, DynamicProtoChangeDetector,
} from 'change_detection/change_detection';
import {Injector} from 'di/di';
export function main() {
@@ -66,7 +67,7 @@ export function main() {
}
if (isPresent(current.element.getAttribute('viewroot'))) {
current.isViewRoot = true;
current.inheritedProtoView = new ProtoView(current.element, new ProtoChangeDetector());
current.inheritedProtoView = new ProtoView(current.element, new DynamicProtoChangeDetector());
} else if (isPresent(parent)) {
current.inheritedProtoView = parent.inheritedProtoView;
}
@@ -205,7 +206,7 @@ export function main() {
var results = pipeline.process(el('<div viewroot prop-binding directives></div>'));
var pv = results[0].inheritedProtoView;
results[0].inheritedElementBinder.nestedProtoView = new ProtoView(
el('<div></div>'), new ProtoChangeDetector());
el('<div></div>'), new DynamicProtoChangeDetector());
instantiateView(pv);
evalContext.prop1 = 'a';
@@ -1,5 +1,6 @@
import {describe, beforeEach, it, expect, iit, ddescribe, el} from 'test_lib/test_lib';
import {isPresent} from 'facade/lang';
import {dynamicChangeDetection} from 'change_detection/change_detection';
import {ElementBinder} from 'core/compiler/element_binder';
import {ProtoViewBuilder} from 'core/compiler/pipeline/proto_view_builder';
import {CompilePipeline} from 'core/compiler/pipeline/compile_pipeline';
@@ -20,7 +21,7 @@ export function main() {
current.variableBindings = MapWrapper.createFromStringMap(variableBindings);
}
current.inheritedElementBinder = new ElementBinder(null, null, null);
}), new ProtoViewBuilder()]);
}), new ProtoViewBuilder(dynamicChangeDetection)]);
}
it('should not create a ProtoView when the isViewRoot flag is not set', () => {
@@ -3,7 +3,7 @@ import {describe, xit, it, expect, beforeEach, ddescribe, iit, el} from 'test_li
import {DOM} from 'facade/dom';
import {Injector} from 'di/di';
import {Lexer, Parser, ChangeDetector} from 'change_detection/change_detection';
import {Lexer, Parser, ChangeDetector, dynamicChangeDetection} from 'change_detection/change_detection';
import {Compiler, CompilerCache} from 'core/compiler/compiler';
import {LifeCycle} from 'core/life_cycle/life_cycle';
@@ -26,7 +26,8 @@ export function main() {
var compiler;
beforeEach( () => {
compiler = new Compiler(null, new TestDirectiveMetadataReader(strategy),
compiler = new Compiler(dynamicChangeDetection, null,
new TestDirectiveMetadataReader(strategy),
new Parser(new Lexer()), new CompilerCache());
});
+38 -35
View File
@@ -5,7 +5,8 @@ import {ShadowDomEmulated} from 'core/compiler/shadow_dom';
import {DirectiveMetadataReader} from 'core/compiler/directive_metadata_reader';
import {Component, Decorator, Template} from 'core/annotations/annotations';
import {OnChange} from 'core/core';
import {Lexer, Parser, ProtoChangeDetector, ChangeDetector} from 'change_detection/change_detection';
import {Lexer, Parser, DynamicProtoChangeDetector,
ChangeDetector} from 'change_detection/change_detection';
import {TemplateConfig} from 'core/annotations/template_config';
import {EventEmitter} from 'core/annotations/events';
import {List, MapWrapper} from 'facade/collection';
@@ -52,7 +53,7 @@ export function main() {
describe('instantiated from protoView', () => {
var view;
beforeEach(() => {
var pv = new ProtoView(el('<div id="1"></div>'), new ProtoChangeDetector());
var pv = new ProtoView(el('<div id="1"></div>'), new DynamicProtoChangeDetector());
view = pv.instantiate(null);
});
@@ -73,7 +74,7 @@ export function main() {
describe('with locals', function() {
var view;
beforeEach(() => {
var pv = new ProtoView(el('<div id="1"></div>'), new ProtoChangeDetector());
var pv = new ProtoView(el('<div id="1"></div>'), new DynamicProtoChangeDetector());
pv.bindVariable('context-foo', 'template-foo');
view = createView(pv);
});
@@ -109,7 +110,7 @@ export function main() {
}
it('should collect the root node in the ProtoView element', () => {
var pv = new ProtoView(templateAwareCreateElement('<div id="1"></div>'), new ProtoChangeDetector());
var pv = new ProtoView(templateAwareCreateElement('<div id="1"></div>'), new DynamicProtoChangeDetector());
var view = pv.instantiate(null);
view.hydrate(null, null, null);
expect(view.nodes.length).toBe(1);
@@ -119,7 +120,7 @@ export function main() {
describe('collect elements with property bindings', () => {
it('should collect property bindings on the root element if it has the ng-binding class', () => {
var pv = new ProtoView(templateAwareCreateElement('<div [prop]="a" class="ng-binding"></div>'), new ProtoChangeDetector());
var pv = new ProtoView(templateAwareCreateElement('<div [prop]="a" class="ng-binding"></div>'), new DynamicProtoChangeDetector());
pv.bindElement(null);
pv.bindElementProperty(parser.parseBinding('a', null), 'prop', reflector.setter('prop'));
@@ -131,7 +132,7 @@ export function main() {
it('should collect property bindings on child elements with ng-binding class', () => {
var pv = new ProtoView(templateAwareCreateElement('<div><span></span><span class="ng-binding"></span></div>'),
new ProtoChangeDetector());
new DynamicProtoChangeDetector());
pv.bindElement(null);
pv.bindElementProperty(parser.parseBinding('b', null), 'a', reflector.setter('a'));
@@ -146,7 +147,7 @@ export function main() {
describe('collect text nodes with bindings', () => {
it('should collect text nodes under the root element', () => {
var pv = new ProtoView(templateAwareCreateElement('<div class="ng-binding">{{}}<span></span>{{}}</div>'), new ProtoChangeDetector());
var pv = new ProtoView(templateAwareCreateElement('<div class="ng-binding">{{}}<span></span>{{}}</div>'), new DynamicProtoChangeDetector());
pv.bindElement(null);
pv.bindTextNode(0, parser.parseBinding('a', null));
pv.bindTextNode(2, parser.parseBinding('b', null));
@@ -160,7 +161,7 @@ export function main() {
it('should collect text nodes with bindings on child elements with ng-binding class', () => {
var pv = new ProtoView(templateAwareCreateElement('<div><span> </span><span class="ng-binding">{{}}</span></div>'),
new ProtoChangeDetector());
new DynamicProtoChangeDetector());
pv.bindElement(null);
pv.bindTextNode(0, parser.parseBinding('b', null));
@@ -176,7 +177,7 @@ export function main() {
describe('inplace instantiation', () => {
it('should be supported.', () => {
var template = el('<div></div>');
var pv = new ProtoView(template, new ProtoChangeDetector());
var pv = new ProtoView(template, new DynamicProtoChangeDetector());
pv.instantiateInPlace = true;
var view = pv.instantiate(null);
view.hydrate(null, null, null);
@@ -185,7 +186,7 @@ export function main() {
it('should be off by default.', () => {
var template = el('<div></div>')
var view = new ProtoView(template, new ProtoChangeDetector())
var view = new ProtoView(template, new DynamicProtoChangeDetector())
.instantiate(null);
view.hydrate(null, null, null);
expect(view.nodes[0]).not.toBe(template);
@@ -202,7 +203,7 @@ export function main() {
describe('create ElementInjectors', () => {
it('should use the directives of the ProtoElementInjector', () => {
var pv = new ProtoView(el('<div class="ng-binding"></div>'), new ProtoChangeDetector());
var pv = new ProtoView(el('<div class="ng-binding"></div>'), new DynamicProtoChangeDetector());
pv.bindElement(new ProtoElementInjector(null, 1, [SomeDirective]));
var view = pv.instantiate(null);
@@ -213,7 +214,7 @@ export function main() {
it('should use the correct parent', () => {
var pv = new ProtoView(el('<div class="ng-binding"><span class="ng-binding"></span></div>'),
new ProtoChangeDetector());
new DynamicProtoChangeDetector());
var protoParent = new ProtoElementInjector(null, 0, [SomeDirective]);
pv.bindElement(protoParent);
pv.bindElement(new ProtoElementInjector(protoParent, 1, [AnotherDirective]));
@@ -227,7 +228,7 @@ export function main() {
it('should not pass the host injector when a parent injector exists', () => {
var pv = new ProtoView(el('<div class="ng-binding"><span class="ng-binding"></span></div>'),
new ProtoChangeDetector());
new DynamicProtoChangeDetector());
var protoParent = new ProtoElementInjector(null, 0, [SomeDirective]);
pv.bindElement(protoParent);
var testProtoElementInjector = new TestProtoElementInjector(protoParent, 1, [AnotherDirective]);
@@ -243,7 +244,7 @@ export function main() {
it('should pass the host injector when there is no parent injector', () => {
var pv = new ProtoView(el('<div class="ng-binding"><span class="ng-binding"></span></div>'),
new ProtoChangeDetector());
new DynamicProtoChangeDetector());
pv.bindElement(new ProtoElementInjector(null, 0, [SomeDirective]));
var testProtoElementInjector = new TestProtoElementInjector(null, 1, [AnotherDirective]);
pv.bindElement(testProtoElementInjector);
@@ -260,7 +261,7 @@ export function main() {
it('should collect a single root element injector', () => {
var pv = new ProtoView(el('<div class="ng-binding"><span class="ng-binding"></span></div>'),
new ProtoChangeDetector());
new DynamicProtoChangeDetector());
var protoParent = new ProtoElementInjector(null, 0, [SomeDirective]);
pv.bindElement(protoParent);
pv.bindElement(new ProtoElementInjector(protoParent, 1, [AnotherDirective]));
@@ -273,7 +274,7 @@ export function main() {
it('should collect multiple root element injectors', () => {
var pv = new ProtoView(el('<div><span class="ng-binding"></span><span class="ng-binding"></span></div>'),
new ProtoChangeDetector());
new DynamicProtoChangeDetector());
pv.bindElement(new ProtoElementInjector(null, 1, [SomeDirective]));
pv.bindElement(new ProtoElementInjector(null, 2, [AnotherDirective]));
@@ -290,7 +291,7 @@ export function main() {
var ctx;
function createComponentWithSubPV(subProtoView) {
var pv = new ProtoView(el('<cmp class="ng-binding"></cmp>'), new ProtoChangeDetector());
var pv = new ProtoView(el('<cmp class="ng-binding"></cmp>'), new DynamicProtoChangeDetector());
var binder = pv.bindElement(new ProtoElementInjector(null, 0, [SomeComponent], true));
binder.componentDirective = someComponentDirective;
binder.nestedProtoView = subProtoView;
@@ -305,7 +306,7 @@ export function main() {
}
it('should expose component services to the component', () => {
var subpv = new ProtoView(el('<span></span>'), new ProtoChangeDetector());
var subpv = new ProtoView(el('<span></span>'), new DynamicProtoChangeDetector());
var pv = createComponentWithSubPV(subpv);
var view = createNestedView(pv);
@@ -317,7 +318,7 @@ export function main() {
it('should expose component services and component instance to directives in the shadow Dom',
() => {
var subpv = new ProtoView(
el('<div dec class="ng-binding">hello shadow dom</div>'), new ProtoChangeDetector());
el('<div dec class="ng-binding">hello shadow dom</div>'), new DynamicProtoChangeDetector());
subpv.bindElement(
new ProtoElementInjector(null, 0, [ServiceDependentDecorator]));
var pv = createComponentWithSubPV(subpv);
@@ -340,7 +341,7 @@ export function main() {
it('dehydration should dehydrate child component views too', () => {
var subpv = new ProtoView(
el('<div dec class="ng-binding">hello shadow dom</div>'), new ProtoChangeDetector());
el('<div dec class="ng-binding">hello shadow dom</div>'), new DynamicProtoChangeDetector());
subpv.bindElement(
new ProtoElementInjector(null, 0, [ServiceDependentDecorator]));
var pv = createComponentWithSubPV(subpv);
@@ -355,7 +356,7 @@ export function main() {
});
it('should create shadow dom', () => {
var subpv = new ProtoView(el('<span>hello shadow dom</span>'), new ProtoChangeDetector());
var subpv = new ProtoView(el('<span>hello shadow dom</span>'), new DynamicProtoChangeDetector());
var pv = createComponentWithSubPV(subpv);
var view = createNestedView(pv);
@@ -364,9 +365,9 @@ export function main() {
});
it('should use the provided shadow DOM strategy', () => {
var subpv = new ProtoView(el('<span>hello shadow dom</span>'), new ProtoChangeDetector());
var subpv = new ProtoView(el('<span>hello shadow dom</span>'), new DynamicProtoChangeDetector());
var pv = new ProtoView(el('<cmp class="ng-binding"></cmp>'), new ProtoChangeDetector());
var pv = new ProtoView(el('<cmp class="ng-binding"></cmp>'), new DynamicProtoChangeDetector());
var binder = pv.bindElement(new ProtoElementInjector(null, 0, [SomeComponentWithEmulatedShadowDom], true));
binder.componentDirective = new DirectiveMetadataReader().read(SomeComponentWithEmulatedShadowDom);
binder.nestedProtoView = subpv;
@@ -380,8 +381,8 @@ export function main() {
describe('with template views', () => {
function createViewWithTemplate() {
var templateProtoView = new ProtoView(
el('<div id="1"></div>'), new ProtoChangeDetector());
var pv = new ProtoView(el('<someTmpl class="ng-binding"></someTmpl>'), new ProtoChangeDetector());
el('<div id="1"></div>'), new DynamicProtoChangeDetector());
var pv = new ProtoView(el('<someTmpl class="ng-binding"></someTmpl>'), new DynamicProtoChangeDetector());
var binder = pv.bindElement(new ProtoElementInjector(null, 0, [SomeTemplate]));
binder.templateDirective = someTemplateDirective;
binder.nestedProtoView = templateProtoView;
@@ -425,7 +426,7 @@ export function main() {
function createProtoView() {
var pv = new ProtoView(el('<div class="ng-binding"><div></div></div>'),
new ProtoChangeDetector());
new DynamicProtoChangeDetector());
pv.bindElement(new TestProtoElementInjector(null, 0, []));
pv.bindEvent('click', parser.parseBinding('callMe(\$event)', null));
return pv;
@@ -460,7 +461,7 @@ export function main() {
it('should support custom event emitters', () => {
var pv = new ProtoView(el('<div class="ng-binding"><div></div></div>'),
new ProtoChangeDetector());
new DynamicProtoChangeDetector());
pv.bindElement(new TestProtoElementInjector(null, 0, [EventEmitterDirective]));
pv.bindEvent('click', parser.parseBinding('callMe(\$event)', null));
@@ -491,7 +492,7 @@ export function main() {
it('should consume text node changes', () => {
var pv = new ProtoView(el('<div class="ng-binding">{{}}</div>'),
new ProtoChangeDetector());
new DynamicProtoChangeDetector());
pv.bindElement(null);
pv.bindTextNode(0, parser.parseBinding('foo', null));
createViewAndChangeDetector(pv);
@@ -503,7 +504,7 @@ export function main() {
it('should consume element binding changes', () => {
var pv = new ProtoView(el('<div class="ng-binding"></div>'),
new ProtoChangeDetector());
new DynamicProtoChangeDetector());
pv.bindElement(null);
pv.bindElementProperty(parser.parseBinding('foo', null), 'id', reflector.setter('id'));
createViewAndChangeDetector(pv);
@@ -515,7 +516,7 @@ export function main() {
it('should consume directive watch expression change', () => {
var pv = new ProtoView(el('<div class="ng-binding"></div>'),
new ProtoChangeDetector());
new DynamicProtoChangeDetector());
pv.bindElement(new ProtoElementInjector(null, 0, [SomeDirective]));
pv.bindDirectiveProperty(0, parser.parseBinding('foo', null), 'prop', reflector.setter('prop'), false);
createViewAndChangeDetector(pv);
@@ -527,7 +528,7 @@ export function main() {
it('should notify a directive about changes after all its properties have been set', () => {
var pv = new ProtoView(el('<div class="ng-binding"></div>'),
new ProtoChangeDetector());
new DynamicProtoChangeDetector());
pv.bindElement(new ProtoElementInjector(null, 0, [DirectiveImplementingOnChange]));
pv.bindDirectiveProperty( 0, parser.parseBinding('a', null), 'a', reflector.setter('a'), false);
@@ -544,7 +545,7 @@ export function main() {
it('should provide a map of updated properties', () => {
var pv = new ProtoView(el('<div class="ng-binding"></div>'),
new ProtoChangeDetector());
new DynamicProtoChangeDetector());
pv.bindElement(new ProtoElementInjector(null, 0, [DirectiveImplementingOnChange]));
pv.bindDirectiveProperty( 0, parser.parseBinding('a', null), 'a', reflector.setter('a'), false);
@@ -569,18 +570,20 @@ export function main() {
var element, pv;
beforeEach(() => {
element = DOM.createElement('div');
pv = new ProtoView(el('<div>hi</div>'), new ProtoChangeDetector());
pv = new ProtoView(el('<div>hi</div>'), new DynamicProtoChangeDetector());
});
it('should create the root component when instantiated', () => {
var rootProtoView = ProtoView.createRootProtoView(pv, element, someComponentDirective);
var rootProtoView = ProtoView.createRootProtoView(pv, element,
someComponentDirective, new DynamicProtoChangeDetector());
var view = rootProtoView.instantiate(null);
view.hydrate(new Injector([]), null, null);
expect(view.rootElementInjectors[0].get(SomeComponent)).not.toBe(null);
});
it('should inject the protoView into the shadowDom', () => {
var rootProtoView = ProtoView.createRootProtoView(pv, element, someComponentDirective);
var rootProtoView = ProtoView.createRootProtoView(pv, element,
someComponentDirective, new DynamicProtoChangeDetector());
var view = rootProtoView.instantiate(null);
view.hydrate(new Injector([]), null, null);
expect(element.shadowRoot.childNodes[0].childNodes[0].nodeValue).toEqual('hi');
+5 -5
View File
@@ -6,10 +6,10 @@ import {DOM} from 'facade/dom';
import {ListWrapper, MapWrapper} from 'facade/collection';
import {Injector} from 'di/di';
import {ProtoElementInjector, ElementInjector} from 'core/compiler/element_injector';
import {ProtoChangeDetector, ChangeDetector, Lexer, Parser} from 'change_detection/change_detection';
import {DynamicProtoChangeDetector, ChangeDetector, Lexer, Parser} from 'change_detection/change_detection';
function createView(nodes) {
var view = new View(null, nodes, new ProtoChangeDetector(), MapWrapper.create());
var view = new View(null, nodes, new DynamicProtoChangeDetector(), MapWrapper.create());
view.init([], [], [], [], [], [], []);
return view;
}
@@ -68,7 +68,7 @@ export function main() {
dom = el(`<div><stuff></stuff><div insert-after-me></div><stuff></stuff></div>`);
var insertionElement = dom.childNodes[1];
parentView = createView([dom.childNodes[0]]);
protoView = new ProtoView(el('<div>hi</div>'), new ProtoChangeDetector());
protoView = new ProtoView(el('<div>hi</div>'), new DynamicProtoChangeDetector());
elementInjector = new ElementInjector(null, null, null, null);
viewPort = new ViewPort(parentView, insertionElement, protoView, elementInjector);
customViewWithOneNode = createView([el('<div>single</div>')]);
@@ -165,7 +165,7 @@ export function main() {
expect(textInViewPort()).toEqual('filler one two');
expect(viewPort.length).toBe(2);
});
it('should keep views hydration state during insert', () => {
var hydratedView = new HydrateAwareFakeView(true);
var dehydratedView = new HydrateAwareFakeView(false);
@@ -212,7 +212,7 @@ export function main() {
viewPort.hydrate(new Injector([]), null);
var pv = new ProtoView(el('<div class="ng-binding">{{}}</div>'),
new ProtoChangeDetector());
new DynamicProtoChangeDetector());
pv.bindElement(new ProtoElementInjector(null, 1, [SomeDirective]));
pv.bindTextNode(0, parser.parseBinding('foo', null));
fancyView = pv.instantiate(null);