From 426e651e80a1e48a46f252c2627e983f2a3f476f Mon Sep 17 00:00:00 2001 From: vsavkin Date: Thu, 31 Jul 2014 16:27:02 -0400 Subject: [PATCH] feature(directive_injector): add View to DirectiveInjector Some directives require access to the current view. Add the view field to the DirectiveInjector class, so it can be injected. --- lib/core_dom/directive_injector.dart | 19 ++++++++++++------- lib/core_dom/element_binder.dart | 4 ++-- .../shadow_dom_component_factory.dart | 6 +++--- .../transcluding_component_factory.dart | 6 +++--- test/core_dom/directive_injector_spec.dart | 13 +++++++++---- test/directive/ng_model_spec.dart | 2 +- 6 files changed, 30 insertions(+), 20 deletions(-) diff --git a/lib/core_dom/directive_injector.dart b/lib/core_dom/directive_injector.dart index 950f9da1f..2bf20a499 100644 --- a/lib/core_dom/directive_injector.dart +++ b/lib/core_dom/directive_injector.dart @@ -111,6 +111,7 @@ class DirectiveInjector implements DirectiveBinder { final Animate _animate; final EventHandler _eventHandler; Scope scope; //TODO(misko): this should be final after we get rid of controller + final View _view; NgElement _ngElement; ElementProbe _elementProbe; @@ -144,15 +145,18 @@ class DirectiveInjector implements DirectiveBinder { static Binding _tempBinding = new Binding(); - DirectiveInjector(this._parent, appInjector, this._node, this._nodeAttrs, - this._eventHandler, this.scope, this._animate) - : _appInjector = appInjector; + DirectiveInjector(DirectiveInjector parent, appInjector, this._node, this._nodeAttrs, + this._eventHandler, this.scope, this._animate, [View view]) + : _parent = parent, + _appInjector = appInjector, + _view = view == null && parent != null ? parent._view : view; DirectiveInjector._default(this._parent, this._appInjector) : _node = null, _nodeAttrs = null, _eventHandler = null, scope = null, + _view = null, _animate = null; void bind(key, {dynamic toValue: DEFAULT_VALUE, @@ -295,6 +299,7 @@ class DirectiveInjector implements DirectiveBinder { currentInjector = currentInjector._parent; } return null; + case VIEW_KEY_ID: return _view; default: new NoProviderError(_KEYS[keyId]); } } @@ -375,8 +380,8 @@ class TemplateDirectiveInjector extends DirectiveInjector { TemplateDirectiveInjector(DirectiveInjector parent, Injector appInjector, Node node, NodeAttrs nodeAttrs, EventHandler eventHandler, - Scope scope, Animate animate, this._viewFactory) - : super(parent, appInjector, node, nodeAttrs, eventHandler, scope, animate); + Scope scope, Animate animate, this._viewFactory, [View view]) + : super(parent, appInjector, node, nodeAttrs, eventHandler, scope, animate, view); Object _getById(int keyId) { @@ -400,9 +405,9 @@ class ComponentDirectiveInjector extends DirectiveInjector { ComponentDirectiveInjector(DirectiveInjector parent, Injector appInjector, EventHandler eventHandler, Scope scope, - this._templateLoader, this._shadowRoot, this._contentPort) + this._templateLoader, this._shadowRoot, this._contentPort, [View view]) : super(parent, appInjector, parent._node, parent._nodeAttrs, eventHandler, scope, - parent._animate) { + parent._animate, view) { // A single component creates a ComponentDirectiveInjector and its DirectiveInjector parent, // so parent should never be null. assert(parent != null); diff --git a/lib/core_dom/element_binder.dart b/lib/core_dom/element_binder.dart index fc00874e2..5049a04ac 100644 --- a/lib/core_dom/element_binder.dart +++ b/lib/core_dom/element_binder.dart @@ -268,9 +268,9 @@ class ElementBinder { eventHandler(parentInjector); if (this is TemplateElementBinder) { nodeInjector = new TemplateDirectiveInjector(parentInjector, _appInjector, - node, nodeAttrs, parentEventHandler, scope, _animate, (this as TemplateElementBinder).templateViewFactory); + node, nodeAttrs, parentEventHandler, scope, _animate, (this as TemplateElementBinder).templateViewFactory, view); } else { - nodeInjector = new DirectiveInjector(parentInjector, _appInjector, node, nodeAttrs, parentEventHandler, scope, _animate); + nodeInjector = new DirectiveInjector(parentInjector, _appInjector, node, nodeAttrs, parentEventHandler, scope, _animate, view); } for(var i = 0; i < directiveRefs.length; i++) { diff --git a/lib/core_dom/shadow_dom_component_factory.dart b/lib/core_dom/shadow_dom_component_factory.dart index 221701575..11cc2097b 100644 --- a/lib/core_dom/shadow_dom_component_factory.dart +++ b/lib/core_dom/shadow_dom_component_factory.dart @@ -121,10 +121,10 @@ class BoundShadowDomComponentFactory implements BoundComponentFactory { } List get callArgs => _CALL_ARGS; - static final _CALL_ARGS = [DIRECTIVE_INJECTOR_KEY, SCOPE_KEY, NG_BASE_CSS_KEY, + static final _CALL_ARGS = [DIRECTIVE_INJECTOR_KEY, SCOPE_KEY, VIEW_KEY, NG_BASE_CSS_KEY, EVENT_HANDLER_KEY]; Function call(dom.Element element) { - return (DirectiveInjector injector, Scope scope, NgBaseCss baseCss, + return (DirectiveInjector injector, Scope scope, View view, NgBaseCss baseCss, EventHandler _) { var s = traceEnter(View_createComponent); try { @@ -166,7 +166,7 @@ class BoundShadowDomComponentFactory implements BoundComponentFactory { var eventHandler = new ShadowRootEventHandler( shadowDom, injector.getByKey(EXPANDO_KEY), injector.getByKey(EXCEPTION_HANDLER_KEY)); shadowInjector = new ComponentDirectiveInjector(injector, _injector, eventHandler, shadowScope, - templateLoader, shadowDom, null); + templateLoader, shadowDom, null, view); shadowInjector.bindByKey(_ref.typeKey, _ref.factory, _ref.paramKeys, _ref.annotation.visibility); if (_componentFactory.config.elementProbeEnabled) { diff --git a/lib/core_dom/transcluding_component_factory.dart b/lib/core_dom/transcluding_component_factory.dart index a3c2b4f60..fe2029223 100644 --- a/lib/core_dom/transcluding_component_factory.dart +++ b/lib/core_dom/transcluding_component_factory.dart @@ -98,7 +98,7 @@ class BoundTranscludingComponentFactory implements BoundComponentFactory { } List get callArgs => _CALL_ARGS; - static var _CALL_ARGS = [ DIRECTIVE_INJECTOR_KEY, SCOPE_KEY, + static var _CALL_ARGS = [ DIRECTIVE_INJECTOR_KEY, SCOPE_KEY, VIEW_KEY, VIEW_CACHE_KEY, HTTP_KEY, TEMPLATE_CACHE_KEY, DIRECTIVE_MAP_KEY, NG_BASE_CSS_KEY, EVENT_HANDLER_KEY]; Function call(dom.Node node) { @@ -107,7 +107,7 @@ class BoundTranscludingComponentFactory implements BoundComponentFactory { _component.cssUrls.isEmpty); var element = node as dom.Element; - return (DirectiveInjector injector, Scope scope, + return (DirectiveInjector injector, Scope scope, View view, ViewCache viewCache, Http http, TemplateCache templateCache, DirectiveMap directives, NgBaseCss baseCss, EventHandler eventHandler) { @@ -145,7 +145,7 @@ class BoundTranscludingComponentFactory implements BoundComponentFactory { childInjector = new ComponentDirectiveInjector(injector, this._injector, eventHandler, shadowScope, templateLoader, new ShadowlessShadowRoot(element), - contentPort); + contentPort, view); childInjector.bindByKey(_ref.typeKey, _ref.factory, _ref.paramKeys, _ref.annotation.visibility); if (childInjectorCompleter != null) { diff --git a/test/core_dom/directive_injector_spec.dart b/test/core_dom/directive_injector_spec.dart index eac9b3b15..802fc5d84 100644 --- a/test/core_dom/directive_injector_spec.dart +++ b/test/core_dom/directive_injector_spec.dart @@ -15,6 +15,7 @@ void main() { describe('base', () { DirectiveInjector injector; Scope scope; + View view; Animate animate; addDirective(Type type, [Visibility visibility]) { @@ -30,13 +31,16 @@ void main() { beforeEach((Scope _scope, Animate _animate) { scope = _scope; animate = _animate; - injector = new DirectiveInjector(null, appInjector, div, new NodeAttrs(div), eventHandler, scope, animate); + view = new View([], scope); + injector = new DirectiveInjector(null, appInjector, div, new NodeAttrs(div), eventHandler, + scope, animate, view); }); it('should return basic types', () { expect(injector.scope).toBe(scope); expect(injector.get(Injector)).toBe(appInjector); expect(injector.get(Scope)).toBe(scope); + expect((injector.get(View))).toBe(view); expect(injector.get(Node)).toBe(div); expect(injector.get(Element)).toBe(div); expect((injector.get(NodeAttrs) as NodeAttrs).element).toBe(div); @@ -48,7 +52,8 @@ void main() { it('should support get from parent methods', () { var newDiv = new DivElement(); var childInjector = new DirectiveInjector( - injector, appInjector, newDiv, new NodeAttrs(newDiv), eventHandler, scope, animate); + injector, appInjector, newDiv, new NodeAttrs(newDiv), eventHandler, + scope, animate, view); expect(childInjector.get(Node)).toBe(newDiv); expect(childInjector.getFromParent(Node)).toBe(div); @@ -79,8 +84,8 @@ void main() { DirectiveInjector leafInjector; beforeEach(() { - childInjector = new DirectiveInjector(injector, appInjector, span, null, null, null, null); - leafInjector = new DirectiveInjector(childInjector, appInjector, span, null, null, null, null); + childInjector = new DirectiveInjector(injector, appInjector, span, null, null, null, null, null); + leafInjector = new DirectiveInjector(childInjector, appInjector, span, null, null, null, null, null); }); it('should not allow reseting visibility', () { diff --git a/test/directive/ng_model_spec.dart b/test/directive/ng_model_spec.dart index e7418dd61..2f5f98e51 100644 --- a/test/directive/ng_model_spec.dart +++ b/test/directive/ng_model_spec.dart @@ -47,7 +47,7 @@ void main() { beforeEach((TestBed tb) { _ = tb; - dirInjector = new DirectiveInjector(null, _.injector, null, null, null, null, null); + dirInjector = new DirectiveInjector(null, _.injector, null, null, null, null, null, null); }); describe('type="text" like', () {