Skip to content

Commit 8faf636

Browse files
committed
refactor(core): remove DynamicComponent
BREAKING CHANGE: A dynamic component is just a component that has no @view annotation…
1 parent b71fe31 commit 8faf636

17 files changed

Lines changed: 76 additions & 123 deletions

File tree

modules/angular2/src/core/annotations/annotations.es6

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,5 @@ export {
77
Component as ComponentAnnotation,
88
Decorator as DecoratorAnnotation,
99
Directive as DirectiveAnnotation,
10-
DynamicComponent as DynamicComponentAnnotation,
11-
Viewport as ViewportAnnotation,
1210
onDestroy, onChange, onAllChangesDone
1311
} from '../annotations_impl/annotations';

modules/angular2/src/core/annotations_impl/annotations.js

Lines changed: 46 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {DEFAULT} from 'angular2/change_detection';
88
/**
99
* Directives allow you to attach behavior to elements in the DOM.
1010
*
11-
* Directive is an abstract concept, instead use concrete directives: {@link Component}, {@link DynamicComponent}, {@link Decorator}.
11+
* Directive is an abstract concept, instead use concrete directives: {@link Component}, or {@link Decorator}.
1212
*
1313
* A directive consists of a single directive annotation and a controller class. When the directive's `selector` matches
1414
* elements in the DOM, the following steps occur:
@@ -542,6 +542,51 @@ export class Directive extends Injectable {
542542
* }
543543
* ```
544544
*
545+
*
546+
* Dynamically loading a component at runtime:
547+
*
548+
* Regular Angular components are statically resolved. Dynamic components allows to resolve a component at runtime
549+
* instead by providing a placeholder into which a regular Angular component can be dynamically loaded. Once loaded,
550+
* the dynamically-loaded component becomes permanent and cannot be changed.
551+
* Dynamic components are declared just like components, but without a `@View` annotation.
552+
*
553+
*
554+
* ## Example
555+
*
556+
* Here we have `DynamicComp` which acts as the placeholder for `HelloCmp`. At runtime, the dynamic component
557+
* `DynamicComp` requests loading of the `HelloCmp` component.
558+
*
559+
* There is nothing special about `HelloCmp`, which is a regular Angular component. It can also be used in other static
560+
* locations.
561+
*
562+
* ```
563+
* @Component({
564+
* selector: 'dynamic-comp'
565+
* })
566+
* class DynamicComp {
567+
* helloCmp:HelloCmp;
568+
* constructor(loader:DynamicComponentLoader, location:ElementRef) {
569+
* loader.load(HelloCmp, location).then((helloCmp) => {
570+
* this.helloCmp = helloCmp;
571+
* });
572+
* }
573+
* }
574+
*
575+
* @Component({
576+
* selector: 'hello-cmp'
577+
* })
578+
* @View({
579+
* template: "{{greeting}}"
580+
* })
581+
* class HelloCmp {
582+
* greeting:string;
583+
* constructor() {
584+
* this.greeting = "hello";
585+
* }
586+
* }
587+
* ```
588+
*
589+
*
545590
* @exportedAs angular2/annotations
546591
*/
547592
export class Component extends Directive {
@@ -639,90 +684,6 @@ export class Component extends Directive {
639684
}
640685
}
641686

642-
/**
643-
* Directive used for dynamically loading components.
644-
*
645-
* Regular Angular components are statically resolved. DynamicComponent allows to you resolve a component at runtime
646-
* instead by providing a placeholder into which a regular Angular component can be dynamically loaded. Once loaded,
647-
* the dynamically-loaded component becomes permanent and cannot be changed.
648-
*
649-
*
650-
* ## Example
651-
*
652-
* Here we have `DynamicComp` which acts as the placeholder for `HelloCmp`. At runtime, the dynamic component
653-
* `DynamicComp` requests loading of the `HelloCmp` component.
654-
*
655-
* There is nothing special about `HelloCmp`, which is a regular Angular component. It can also be used in other static
656-
* locations.
657-
*
658-
* ```
659-
* @DynamicComponent({
660-
* selector: 'dynamic-comp'
661-
* })
662-
* class DynamicComp {
663-
* helloCmp:HelloCmp;
664-
* constructor(loader:DynamicComponentLoader, location:PrivateComponentLocation) {
665-
* loader.load(HelloCmp, location).then((helloCmp) => {
666-
* this.helloCmp = helloCmp;
667-
* });
668-
* }
669-
* }
670-
*
671-
* @Component({
672-
* selector: 'hello-cmp'
673-
* })
674-
* @View({
675-
* template: "{{greeting}}"
676-
* })
677-
* class HelloCmp {
678-
* greeting:string;
679-
* constructor() {
680-
* this.greeting = "hello";
681-
* }
682-
* }
683-
* ```
684-
*
685-
*
686-
*
687-
* @exportedAs angular2/annotations
688-
*/
689-
export class DynamicComponent extends Directive {
690-
/**
691-
* Same as `injectables` in the {@link Component}.
692-
*/
693-
// TODO(vsankin): Please extract into AbstractComponent
694-
injectables:any; //List;
695-
696-
@CONST()
697-
constructor({
698-
selector,
699-
properties,
700-
events,
701-
hostListeners,
702-
hostProperties,
703-
injectables,
704-
lifecycle
705-
}:{
706-
selector:string,
707-
properties:any,
708-
events:List,
709-
hostListeners:any,
710-
hostProperties:any,
711-
injectables:List,
712-
lifecycle:List
713-
}={}) {
714-
super({
715-
selector: selector,
716-
properties: properties,
717-
events: events,
718-
hostListeners: hostListeners,
719-
hostProperties: hostProperties,
720-
lifecycle: lifecycle
721-
});
722-
723-
this.injectables = injectables;
724-
}
725-
}
726687

727688
/**
728689
* Directive that attaches behavior to DOM elements.

modules/angular2/src/core/compiler/compiler.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
44
import {List, ListWrapper, Map, MapWrapper} from 'angular2/src/facade/collection';
55

66
import {DirectiveMetadataReader} from './directive_metadata_reader';
7-
import {Component, DynamicComponent, Decorator} from '../annotations_impl/annotations';
7+
import {Component, Decorator} from '../annotations_impl/annotations';
88
import {AppProtoView} from './view';
99
import {ProtoViewRef} from './view_ref';
1010
import {DirectiveBinding} from './element_injector';
@@ -128,8 +128,10 @@ export class Compiler {
128128
// It happens when a template references a component multiple times.
129129
return pvPromise;
130130
}
131-
132131
var template = this._templateResolver.resolve(component);
132+
if (isBlank(template)) {
133+
return null;
134+
}
133135
if (isPresent(template.renderer)) {
134136
var directives = [];
135137
pvPromise = this._renderer.createImperativeComponentProtoView(template.renderer).then( (renderPv) => {
@@ -174,9 +176,7 @@ export class Compiler {
174176
};
175177
var nestedCall = null;
176178
if (isPresent(nestedComponent)) {
177-
if (!(nestedComponent.annotation instanceof DynamicComponent)) {
178-
nestedCall = this._compile(nestedComponent);
179-
}
179+
nestedCall = this._compile(nestedComponent);
180180
} else if (isPresent(nestedRenderProtoView)) {
181181
nestedCall = this._compileNestedProtoViews(componentBinding, nestedRenderProtoView, directives, false);
182182
}
@@ -231,7 +231,7 @@ export class Compiler {
231231
var ann = directiveBinding.annotation;
232232
var renderType;
233233
var compileChildren = true;
234-
if ((ann instanceof Component) || (ann instanceof DynamicComponent)) {
234+
if (ann instanceof Component) {
235235
renderType = renderApi.DirectiveMetadata.COMPONENT_TYPE;
236236
} else if (ann instanceof Decorator) {
237237
renderType = renderApi.DirectiveMetadata.DECORATOR_TYPE;

modules/angular2/src/core/compiler/proto_view_factory.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {isPresent, isBlank} from 'angular2/src/facade/lang';
44
import {reflector} from 'angular2/src/reflection/reflection';
55

66
import {ChangeDetection, DirectiveIndex} from 'angular2/change_detection';
7-
import {Component, DynamicComponent} from '../annotations_impl/annotations';
7+
import {Component} from '../annotations_impl/annotations';
88

99
import * as renderApi from 'angular2/src/render/api';
1010
import {AppProtoView} from './view';
@@ -162,7 +162,7 @@ class SortedDirectives {
162162
this.componentDirective = null;
163163
ListWrapper.forEach(renderDirectives, (renderDirectiveBinder) => {
164164
var directiveBinding = allDirectives[renderDirectiveBinder.directiveIndex];
165-
if ((directiveBinding.annotation instanceof Component) || (directiveBinding.annotation instanceof DynamicComponent)) {
165+
if (directiveBinding.annotation instanceof Component) {
166166
// component directives need to be the first binding in ElementInjectors!
167167
this.componentDirective = directiveBinding;
168168
ListWrapper.insert(this.renderDirectives, 0, renderDirectiveBinder);

modules/angular2/src/core/compiler/template_resolver.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export class TemplateResolver {
3434
return annotation;
3535
}
3636
}
37-
38-
throw new BaseException(`No template found for ${stringify(component)}`);
37+
// No annotation = dynamic component!
38+
return null;
3939
}
4040
}

modules/angular2/src/core/decorators/decorators.es6

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import {
22
ComponentAnnotation,
3-
DecoratorAnnotation,
4-
DynamicComponentAnnotation,
5-
ViewportAnnotation} from '../annotations/annotations';
3+
DecoratorAnnotation
4+
} from '../annotations/annotations';
65
import {ViewAnnotation} from '../annotations/view';
76
import {AncestorAnnotation, ParentAnnotation} from '../annotations/visibility';
87
import {AttributeAnnotation, QueryAnnotation} from '../annotations/di';
@@ -25,8 +24,6 @@ function makeDecorator(annotationCls) {
2524
/* from annotations */
2625
export var Component = makeDecorator(ComponentAnnotation);
2726
export var Decorator = makeDecorator(DecoratorAnnotation);
28-
export var DynamicComponent = makeDecorator(DynamicComponentAnnotation);
29-
export var Viewport = makeDecorator(ViewportAnnotation);
3027

3128
/* from di */
3229
export var Attribute = makeDecorator(AttributeAnnotation);

modules/angular2/src/mock/template_resolver_mock.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ export class MockTemplateResolver extends TemplateResolver {
7878
if (isBlank(view)) {
7979
view = super.resolve(component);
8080
}
81+
if (isBlank(view)) {
82+
// dynamic components
83+
return null;
84+
}
8185

8286
var directives = view.directives;
8387
var overrides = MapWrapper.get(this._directiveOverrides, component);

modules/angular2/test/core/application_spec.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,6 @@ export function main() {
8787
});
8888

8989
describe('bootstrap factory method', () => {
90-
it('should throw if no View found', inject([AsyncTestCompleter], (async) => {
91-
var refPromise = bootstrap(HelloRootMissingTemplate, testBindings, (e,t) => {throw e;});
92-
PromiseWrapper.then(refPromise, null, (reason) => {
93-
expect(reason.message).toContain('No template found for HelloRootMissingTemplate');
94-
async.done();
95-
});
96-
}));
97-
9890
it('should throw if bootstrapped Directive is not a Component', inject([AsyncTestCompleter], (async) => {
9991
var refPromise = bootstrap(HelloRootDirectiveIsNotCmp, testBindings, (e,t) => {throw e;});
10092
PromiseWrapper.then(refPromise, null, (reason) => {

modules/angular2/test/core/compiler/compiler_spec.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
2121
import {AppProtoView} from 'angular2/src/core/compiler/view';
2222
import {ElementBinder} from 'angular2/src/core/compiler/element_binder';
2323
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
24-
import {Component, DynamicComponent, Decorator} from 'angular2/src/core/annotations_impl/annotations';
24+
import {Component, Decorator} from 'angular2/src/core/annotations_impl/annotations';
2525
import {Attribute} from 'angular2/src/core/annotations_impl/di';
2626
import {View} from 'angular2/src/core/annotations_impl/view';
2727
import {internalProtoView} from 'angular2/src/core/compiler/view_ref';
@@ -490,7 +490,7 @@ class NestedComponent {}
490490

491491
class RecursiveComponent {}
492492

493-
@DynamicComponent()
493+
@Component()
494494
class SomeDynamicComponentDirective {}
495495

496496
@Decorator()
@@ -554,7 +554,8 @@ class FakeTemplateResolver extends TemplateResolver {
554554
resolve(component: Type): View {
555555
var template = MapWrapper.get(this._cmpTemplates, component);
556556
if (isBlank(template)) {
557-
throw 'No template';
557+
// dynamic component
558+
return null;
558559
}
559560
return template;
560561
}

modules/angular2/test/core/compiler/dynamic_component_loader_spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616

1717
import {TestBed} from 'angular2/src/test_lib/test_bed';
1818

19-
import {Decorator, Component, DynamicComponent} from 'angular2/src/core/annotations_impl/annotations';
19+
import {Decorator, Component} from 'angular2/src/core/annotations_impl/annotations';
2020
import {View} from 'angular2/src/core/annotations_impl/view';
2121
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
2222
import {ElementRef} from 'angular2/src/core/compiler/element_ref';
@@ -229,7 +229,7 @@ class ChildComp {
229229
class DynamicallyCreatedComponentService {
230230
}
231231

232-
@DynamicComponent({
232+
@Component({
233233
selector: 'dynamic-comp'
234234
})
235235
class DynamicComp {

0 commit comments

Comments
 (0)