From 3a53f67911967f90200f16addb7758e58e4775f5 Mon Sep 17 00:00:00 2001 From: vsavkin Date: Fri, 15 May 2015 15:54:54 -0700 Subject: [PATCH] feat(di): removed publishAs BREAKING CHANGES Removes the publishAs property from the Component annotation. --- .../src/core/annotations_impl/annotations.js | 42 +----- .../src/core/compiler/element_injector.js | 20 --- .../core/compiler/element_injector_spec.js | 49 ------- .../test/core/compiler/integration_spec.js | 129 ------------------ 4 files changed, 2 insertions(+), 238 deletions(-) diff --git a/modules/angular2/src/core/annotations_impl/annotations.js b/modules/angular2/src/core/annotations_impl/annotations.js index 76634ede25..6836f1bfe1 100644 --- a/modules/angular2/src/core/annotations_impl/annotations.js +++ b/modules/angular2/src/core/annotations_impl/annotations.js @@ -845,41 +845,6 @@ export class Component extends Directive { */ injectables:List; - // TODO(naomib): needs documentation - /** - * Dependency injection tokens that this component publishes _itself_ to its - * children in its view via the application injector. - * - * ## Examples - * - * Imagine you have parent component that implements the [RpcService] - * interface. It can pose as [RpcService] to its children. Child components - * do not need to know about this fact. They only need to declare their - * dependency on [RpcService] without knowing exactly how it is provided. - * - * ``` - * @Component({ - * selector: 'parent', - * publishAs: [RpcService] - * }) - * @View({ - * template: '', - * directives: [Child] - * }) - * class Parent implements RpcService { - * } - * - * @Component({ - * selector: 'child' - * }) - * class Child { - * // Just asks for RpcService; doesn't know that it's Parent. - * constructor(RpcService rpc); - * } - * ``` - */ - publishAs:List; - @CONST() constructor({ selector, @@ -892,8 +857,7 @@ export class Component extends Directive { injectables, lifecycle, changeDetection = DEFAULT, - compileChildren = true, - publishAs + compileChildren = true }:{ selector:string, properties:Object, @@ -905,8 +869,7 @@ export class Component extends Directive { injectables:List, lifecycle:List, changeDetection:string, - compileChildren:boolean, - publishAs:List + compileChildren:boolean }={}) { super({ @@ -923,7 +886,6 @@ export class Component extends Directive { this.changeDetection = changeDetection; this.injectables = injectables; - this.publishAs = publishAs; } } diff --git a/modules/angular2/src/core/compiler/element_injector.js b/modules/angular2/src/core/compiler/element_injector.js index e2bfead4d4..6f69324952 100644 --- a/modules/angular2/src/core/compiler/element_injector.js +++ b/modules/angular2/src/core/compiler/element_injector.js @@ -227,18 +227,12 @@ export class DirectiveDependency extends Dependency { export class DirectiveBinding extends ResolvedBinding { resolvedInjectables:List; metadata: DirectiveMetadata; - publishAs: List; constructor(key:Key, factory:Function, dependencies:List, providedAsPromise:boolean, resolvedInjectables:List, metadata:DirectiveMetadata, annotation: Directive) { super(key, factory, dependencies, providedAsPromise); this.resolvedInjectables = resolvedInjectables; this.metadata = metadata; - if (annotation instanceof Component) { - this.publishAs = annotation.publishAs; - } else { - this.publishAs = null; - } } get callOnDestroy() { @@ -678,20 +672,6 @@ export class ElementInjector extends TreeNode { var p = this._proto; if (isPresent(p._keyId0)) this._getDirectiveByKeyId(p._keyId0); - if (isPresent(shadowDomAppInjector)) { - var publishAs = this._proto._binding0.publishAs; - if (isPresent(publishAs) && publishAs.length > 0) { - // If there's a component directive on this element injector, then - // 0-th key must contain the directive itself. - // TODO(yjbanov): need to make injector creation faster: - // - remove flattening of bindings array - // - precalc token key - this._shadowDomAppInjector = shadowDomAppInjector.resolveAndCreateChild( - ListWrapper.map(publishAs, (token) => { - return bind(token).toValue(this.getComponent()); - })); - } - } if (isPresent(p._keyId1)) this._getDirectiveByKeyId(p._keyId1); if (isPresent(p._keyId2)) this._getDirectiveByKeyId(p._keyId2); if (isPresent(p._keyId3)) this._getDirectiveByKeyId(p._keyId3); diff --git a/modules/angular2/test/core/compiler/element_injector_spec.js b/modules/angular2/test/core/compiler/element_injector_spec.js index 470f745f78..97c81f2539 100644 --- a/modules/angular2/test/core/compiler/element_injector_spec.js +++ b/modules/angular2/test/core/compiler/element_injector_spec.js @@ -195,30 +195,6 @@ class TestNode extends TreeNode { } } -// TypeScript erases interfaces, so it has to be a class -class ParentInterface {} - -class ParentComponent extends ParentInterface { -} - -class AppDependency { - parent:ParentInterface; - - constructor(p:ParentInterface) { - this.parent = p; - } -} - -class ChildComponent { - parent:ParentInterface; - appDependency:AppDependency; - - constructor(p:ParentInterface, a:AppDependency) { - this.parent = p; - this.appDependency = a; - } -} - export function main() { var defaultPreBuiltObjects = new PreBuiltObjects(null, null, null); var appInjector = Injector.resolveAndCreate([]); @@ -647,31 +623,6 @@ export function main() { inj.clearDirectives(); expect(destroy.onDestroyCounter).toBe(1); }); - - it("should publish component to its children via app injector when requested", function() { - var parentDirective = new Component({ - selector: 'parent', - publishAs: [ParentInterface] - }); - var parentBinding = DirectiveBinding.createFromType(ParentComponent, parentDirective); - - var childDirective = new Component({ - selector: 'child', - injectables: [AppDependency] - }); - var childBinding = DirectiveBinding.createFromType(ChildComponent, childDirective); - - var child = hostShadowInjectors([parentBinding], [childBinding], true, true); - var d = child.get(ChildComponent); - - // Verify that the child component can inject parent via interface binding - expect(d).toBeAnInstanceOf(ChildComponent); - expect(d.parent).toBeAnInstanceOf(ParentComponent); - - // Verify that the binding is available down the dependency tree - expect(d.appDependency.parent).toBeAnInstanceOf(ParentComponent); - expect(d.parent).toBe(d.appDependency.parent); - }); }); describe("dynamicallyCreateComponent", () => { diff --git a/modules/angular2/test/core/compiler/integration_spec.js b/modules/angular2/test/core/compiler/integration_spec.js index 7ad27a3e6a..8f3186a7ce 100644 --- a/modules/angular2/test/core/compiler/integration_spec.js +++ b/modules/angular2/test/core/compiler/integration_spec.js @@ -986,71 +986,6 @@ export function main() { })); } }); - - describe('dependency injection', () => { - - it('should publish parent component to shadow DOM via publishAs', - inject([TestBed, AsyncTestCompleter, Compiler], (tb, async, compiler) => { - tb.overrideView(MyComp, new View({ - template: ``, - directives: [ParentComponent] - })); - - tb.createView(MyComp).then((view) => { - view.detectChanges(); - expect(view.rootNodes).toHaveText( - 'Parent,Parent'); - async.done(); - }); - })); - - it('should override parent bindings via publishAs', - inject([TestBed, AsyncTestCompleter, Compiler], (tb, async, compiler) => { - tb.overrideView(MyComp, new View({ - template: ``, - directives: [RecursiveParentComponent] - })); - - tb.createView(MyComp).then((view) => { - view.detectChanges(); - expect(view.rootNodes).toHaveText( - 'ParentInterface,RecursiveParent,RecursiveParent'); - async.done(); - }); - })); - - // [DynamicComponentLoader] already supports providing a custom - // injector as an argument to `loadIntoExistingLocation`, which should - // be used instead of `publishAs`. - // - // Conceptually dynamically loaded components are loaded _instead_ of - // the dynamic component itself. The dynamic component does not own the - // shadow DOM. It's the loaded component that creates that shadow DOM. - it('should not publish into dynamically instantiated components via publishAs', - inject([TestBed, AsyncTestCompleter, Compiler], (tb, async, compiler) => { - tb.overrideView(MyComp, new View({ - template: ``, - directives: [DynamicParentComponent] - })); - - tb.createView(MyComp).then((view) => { - view.detectChanges(); - var comp = view.rawView.locals.get("cmp"); - PromiseWrapper.then(comp.done, - (value) => { - throw new BaseException(`Expected to throw error, but got value ${value}`); - }, - (err) => { - expect(err.message) - .toEqual('No provider for ParentInterface! (ChildComponent -> ParentInterface)'); - async.done(); - } - ); - }); - })); - - }); - }); } @@ -1479,70 +1414,6 @@ class NeedsPublicApi { } } -class ParentInterface { - message:String; - constructor() { - this.message = 'ParentInterface'; - } -} - -@Component({ - selector: 'parent', - publishAs: [ParentInterface] -}) -@View({ - template: ``, - directives: [ChildComponent] -}) -class ParentComponent extends ParentInterface { - message:String; - constructor() { - super(); - this.message = 'Parent'; - } -} - -@Component({ - injectables: [ParentInterface], - selector: 'recursive-parent', - publishAs: [ParentInterface] -}) -@View({ - template: `{{parentService.message}},`, - directives: [ChildComponent] -}) -class RecursiveParentComponent extends ParentInterface { - parentService:ParentInterface; - message:String; - constructor(parentService:ParentInterface) { - super(); - this.message = 'RecursiveParent'; - this.parentService = parentService; - } -} - -@Component({ - selector: 'dynamic-parent', - publishAs: [ParentInterface] -}) -class DynamicParentComponent extends ParentInterface { - message:String; - done; - constructor(loader:DynamicComponentLoader, location:ElementRef) { - super(); - this.message = 'DynamicParent'; - this.done = loader.loadIntoExistingLocation(ChildComponent, location); - } -} - -class AppDependency { - parent:ParentInterface; - - constructor(p:ParentInterface) { - this.parent = p; - } -} - @Component({ selector: 'child', injectables: [AppDependency]