refactor(core): rename ViewContainer to ViewContainerRef
This also renames InternalAppViewContainer into AppViewContainer Related to #1477 Closes #1554
This commit is contained in:
@ -6,7 +6,7 @@ Directives are the cornerstone of an Angular application. We use Directives to b
|
||||
|
||||
Angular applications do not have a main method. Instead they have a root Component. Dependency Injection then assembles the directives into a working Angular application.
|
||||
|
||||
There are three different kinds of directives (described in more detail in later sections).
|
||||
There are three different kinds of directives (described in more detail in later sections).
|
||||
|
||||
1. *Decorators*: can be placed on any DOM element and can be combined with other directives.
|
||||
2. *Components*: Components have an encapsulated view and can configure injectors.
|
||||
@ -16,7 +16,7 @@ There are three different kinds of directives (described in more detail in later
|
||||
|
||||
## CSS Selectors
|
||||
|
||||
Directives are instantiated whenever the CSS selector matches the DOM structure.
|
||||
Directives are instantiated whenever the CSS selector matches the DOM structure.
|
||||
|
||||
Angular supports these CSS selector constructs:
|
||||
* Element name: `name`
|
||||
@ -29,7 +29,7 @@ Angular supports these CSS selector constructs:
|
||||
|
||||
Angular does not support these (and any CSS selector which crosses element boundaries):
|
||||
* Descendant: `body div`
|
||||
* Direct descendant: `body > div`
|
||||
* Direct descendant: `body > div`
|
||||
* Adjacent: `div + table`
|
||||
* Sibling: `div ~ table`
|
||||
* Wildcard: `*`
|
||||
@ -68,10 +68,10 @@ Here is a trivial example of a tooltip decorator. The directive will log a toolt
|
||||
@Decorator({
|
||||
selector: '[tooltip]', // CSS Selector which triggers the decorator
|
||||
properties: { // List which properties need to be bound
|
||||
text: 'tooltip' // - DOM element tooltip property should be
|
||||
text: 'tooltip' // - DOM element tooltip property should be
|
||||
}, // mapped to the directive text property.
|
||||
hostListeners: { // List which events need to be mapped.
|
||||
mouseover: 'show' // - Invoke the show() method every time
|
||||
mouseover: 'show' // - Invoke the show() method every time
|
||||
} // the mouseover event is fired.
|
||||
})
|
||||
class Form { // Directive controller class, instantiated
|
||||
@ -121,14 +121,14 @@ Example of a component:
|
||||
templateUrl: 'pane.html' | - URL of template HTML
|
||||
}) |
|
||||
class Pane { | Component controller class
|
||||
title:string; | - title property
|
||||
title:string; | - title property
|
||||
open:boolean;
|
||||
|
||||
|
||||
constructor() {
|
||||
this.title = '';
|
||||
this.open = true;
|
||||
}
|
||||
|
||||
|
||||
// Public API
|
||||
toggle() => this.open = !this.open;
|
||||
open() => this.open = true;
|
||||
@ -165,12 +165,12 @@ Example of usage:
|
||||
|
||||
## Viewport
|
||||
|
||||
Viewport is a directive which can control instantiation of child views which are then inserted into the DOM. (Examples are `if` and `for`.)
|
||||
Viewport is a directive which can control instantiation of child views which are then inserted into the DOM. (Examples are `if` and `for`.)
|
||||
|
||||
* Viewports can only be placed on `<template>` elements (or the short hand version which uses `<element template>` attribute.)
|
||||
* Only one viewport can be present per DOM template element.
|
||||
* The viewport is created over the `template` element. This is known as the `ViewContainer`.
|
||||
* Viewport can insert child views into the `ViewContainer`. The child views show up as siblings of the `Viewport` in the DOM.
|
||||
* The viewport is created over the `template` element. This is known as the `ViewContainerRef`.
|
||||
* Viewport can insert child views into the `ViewContainerRef`. The child views show up as siblings of the `Viewport` in the DOM.
|
||||
|
||||
>> TODO(misko): Relationship with Injection
|
||||
>> TODO(misko): Instantiator can not be injected into child Views
|
||||
@ -184,10 +184,10 @@ Viewport is a directive which can control instantiation of child views which are
|
||||
}
|
||||
})
|
||||
export class If {
|
||||
viewContainer: ViewContainer;
|
||||
viewContainer: ViewContainerRef;
|
||||
view: View;
|
||||
|
||||
constructor(viewContainer: ViewContainer) {
|
||||
constructor(viewContainer: ViewContainerRef) {
|
||||
this.viewContainer = viewContainer;
|
||||
this.view = null;
|
||||
}
|
||||
@ -220,30 +220,30 @@ To better understand the kinds of injections which are supported in Angular we h
|
||||
|
||||
### Injecting Services
|
||||
|
||||
Service injection is the most straight forward kind of injection which Angular supports. It involves a component configuring the `injectables` and then letting the directive ask for the configured service.
|
||||
Service injection is the most straight forward kind of injection which Angular supports. It involves a component configuring the `injectables` and then letting the directive ask for the configured service.
|
||||
|
||||
This example illustrates how to inject `MyService` into `House` directive.
|
||||
|
||||
|
||||
```
|
||||
class MyService {} | Assume a service which needs to be injected
|
||||
class MyService {} | Assume a service which needs to be injected
|
||||
| into a directive.
|
||||
|
|
||||
@Component({ | Assume a top level application component which
|
||||
@Component({ | Assume a top level application component which
|
||||
selector: 'my-app', | configures the services to be injected.
|
||||
injectables: [MyService] |
|
||||
injectables: [MyService] |
|
||||
}) |
|
||||
@View({ | Assume we have a template that needs to be
|
||||
templateUrl: 'my_app.html', | configured with directives to be injected.
|
||||
directives: [House] |
|
||||
directives: [House] |
|
||||
}) |
|
||||
class MyApp {} |
|
||||
|
|
||||
@Decorator({ | This is the directive into which we would like
|
||||
@Decorator({ | This is the directive into which we would like
|
||||
selector: '[house]' | to inject the MyService.
|
||||
}) |
|
||||
class House { |
|
||||
constructor(myService:MyService) { | Notice that in the constructor we can simply
|
||||
constructor(myService:MyService) { | Notice that in the constructor we can simply
|
||||
} | ask for MyService.
|
||||
} |
|
||||
|
||||
@ -252,7 +252,7 @@ class House { |
|
||||
|
||||
Assume the following DOM structure for `my_app.html`:
|
||||
```
|
||||
<div house> | The house attribute triggers the creation of the House directive.
|
||||
<div house> | The house attribute triggers the creation of the House directive.
|
||||
</div> | This is equivalent to:
|
||||
| new House(injector.get(MyService));
|
||||
```
|
||||
@ -264,7 +264,7 @@ Injecting other directives into directives follows a similar mechanism as inject
|
||||
|
||||
There are five kinds of visibilities:
|
||||
|
||||
* (no annotation): Inject dependant directives only if they are on the current element.
|
||||
* (no annotation): Inject dependant directives only if they are on the current element.
|
||||
* `@ancestor`: Inject a directive if it is at any element above the current element.
|
||||
* `@parent`: Inject a directive which is direct parent of the current element.
|
||||
* `@child`: Inject a list of direct children which match a given type. (Used with `Query`)
|
||||
@ -278,8 +278,8 @@ Here is an example of the kinds of injections which can be achieved:
|
||||
```
|
||||
@Component({ |
|
||||
selector: 'my-app' |
|
||||
}) |
|
||||
@View({ |
|
||||
}) |
|
||||
@View({ |
|
||||
templateUrl: 'my_app.html', |
|
||||
directives: [Form, FieldSet, |
|
||||
Field, Primary] |
|
||||
@ -290,15 +290,15 @@ class MyApp {} |
|
||||
class Form { |
|
||||
constructor( |
|
||||
@descendant sets:Query<FieldSet> |
|
||||
) { |
|
||||
} |
|
||||
) { |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@Decorator({ selector: 'fieldset' }) |
|
||||
class FieldSet { |
|
||||
constructor( |
|
||||
@child sets:Query<Field> |
|
||||
) { ... } |
|
||||
) { ... } |
|
||||
} |
|
||||
|
|
||||
@Decorator({ selector: 'field' }) |
|
||||
@ -306,12 +306,12 @@ class Field { |
|
||||
constructor( |
|
||||
@ancestor field:Form, |
|
||||
@parent field:FieldSet, |
|
||||
) { ... } |
|
||||
) { ... } |
|
||||
} |
|
||||
|
|
||||
@Decorator({ selector: '[primary]'}) |
|
||||
class Primary { |
|
||||
constructor(field:Field ) { ... } |
|
||||
constructor(field:Field ) { ... } |
|
||||
} |
|
||||
```
|
||||
|
||||
@ -324,7 +324,7 @@ Assume the following DOM structure for `my_app.html`:
|
||||
<field></field> |
|
||||
</fieldset> |
|
||||
</div> |
|
||||
</form> |
|
||||
</form> |
|
||||
```
|
||||
|
||||
|
||||
|
@ -2,24 +2,24 @@
|
||||
|
||||
## Overview
|
||||
|
||||
This document explains the concept of a View.
|
||||
A View is a core primitive used by angular to render the DOM tree.
|
||||
This document explains the concept of a View.
|
||||
A View is a core primitive used by angular to render the DOM tree.
|
||||
A ViewPort is location in a View which can accept child Views.
|
||||
Every ViewPort has an associated ViewContainer than can contain any number of child Views.
|
||||
Every ViewPort has an associated ViewContainerRef than can contain any number of child Views.
|
||||
Views form a tree structure which mimics the DOM tree.
|
||||
|
||||
* View is a core rendering construct. A running application is just a collection of Views which are
|
||||
nested in a tree like structure. The View tree is a simplified version of the DOM tree. A View can
|
||||
have a single DOM Element or large DOM structures. The key is that the DOM tree in the View can
|
||||
* View is a core rendering construct. A running application is just a collection of Views which are
|
||||
nested in a tree like structure. The View tree is a simplified version of the DOM tree. A View can
|
||||
have a single DOM Element or large DOM structures. The key is that the DOM tree in the View can
|
||||
not undergo structural changes (only property changes).
|
||||
* Views represent a running instance of a DOM View. This implies that while elements in a View
|
||||
can change properties, they can not change structurally. (Structural changes such as, adding or
|
||||
* Views represent a running instance of a DOM View. This implies that while elements in a View
|
||||
can change properties, they can not change structurally. (Structural changes such as, adding or
|
||||
removing elements requires adding or removing child Views into ViewContainers).
|
||||
* View can have zero or more ViewPorts. A ViewPort is a marker in the DOM which allows
|
||||
* View can have zero or more ViewPorts. A ViewPort is a marker in the DOM which allows
|
||||
the insertion of child Views.
|
||||
* Views are created from a ProtoView. A ProtoView is a compiled DOM View which is efficient at
|
||||
* Views are created from a ProtoView. A ProtoView is a compiled DOM View which is efficient at
|
||||
creating Views.
|
||||
* View contains a context object. The context represents the object instance against which all
|
||||
* View contains a context object. The context represents the object instance against which all
|
||||
expressions are evaluated.
|
||||
* View contains a ChangeDetector for looking for detecting changes to the model.
|
||||
* View contains ElementInjector for creating Directives.
|
||||
@ -51,9 +51,9 @@ And assume following HTML View:
|
||||
</div>
|
||||
```
|
||||
|
||||
The above template is compiled by the Compiler to create a ProtoView. The ProtoView is then used to
|
||||
create an instance of the View. The instantiation process involves cloning the above template and
|
||||
locating all of the elements which contain bindings and finally instantiating the Directives
|
||||
The above template is compiled by the Compiler to create a ProtoView. The ProtoView is then used to
|
||||
create an instance of the View. The instantiation process involves cloning the above template and
|
||||
locating all of the elements which contain bindings and finally instantiating the Directives
|
||||
associated with the template. (See compilation for more details.)
|
||||
|
||||
```
|
||||
@ -81,13 +81,13 @@ Note:
|
||||
* View knows which expressions need to be watched.
|
||||
* View knows what needs to be updated if the watched expression changes.
|
||||
* All DOM elements are owned by single instance of the view.
|
||||
* The structure of the DOM can not change during runtime. To allow structural changes to the DOM we need
|
||||
* The structure of the DOM can not change during runtime. To allow structural changes to the DOM we need
|
||||
to understand Composed View.
|
||||
|
||||
|
||||
## Composed View
|
||||
|
||||
An important part of an application is to be able to change the DOM structure to render data for the
|
||||
An important part of an application is to be able to change the DOM structure to render data for the
|
||||
user. In Angular this is done by inserting child views into the ViewPort.
|
||||
|
||||
Let's start with a View such as:
|
||||
@ -123,12 +123,12 @@ The next step is to compose these two ProtoViews into an actual view which is re
|
||||
</ul> | viewA(someContext)
|
||||
```
|
||||
|
||||
*Step2:* Instantiate `Foreach` directive which will receive the `ViewContainer`. (The ViewContainer
|
||||
*Step2:* Instantiate `Foreach` directive which will receive the `ViewContainerRef`. (The ViewContainerRef
|
||||
has a reference to `protoViewA`).
|
||||
|
||||
|
||||
*Step3:* As the `Foreach` directive unrolls it asks the `ViewContainer` to instantiate `protoViewB` and insert
|
||||
it after the `ViewPort` anchor. This is repeated for each `person` in `people`. Notice that
|
||||
*Step3:* As the `Foreach` directive unrolls it asks the `ViewContainerRef` to instantiate `protoViewB` and insert
|
||||
it after the `ViewPort` anchor. This is repeated for each `person` in `people`. Notice that
|
||||
|
||||
```
|
||||
<ul> | viewA(someContext)
|
||||
@ -138,9 +138,9 @@ it after the `ViewPort` anchor. This is repeated for each `person` in `people`.
|
||||
</ul> | viewA(someContext)
|
||||
```
|
||||
|
||||
*Step4:* All of the bindings in the child Views are updated. Notice that in the case of `Foreach`
|
||||
the evaluation context for the `viewB0` and `viewB1` are `locals0` and `locals1` respectively.
|
||||
Locals allow the introduction of new local variables visible only within the scope of the View, and
|
||||
*Step4:* All of the bindings in the child Views are updated. Notice that in the case of `Foreach`
|
||||
the evaluation context for the `viewB0` and `viewB1` are `locals0` and `locals1` respectively.
|
||||
Locals allow the introduction of new local variables visible only within the scope of the View, and
|
||||
delegate any unknown references to the parent context.
|
||||
|
||||
```
|
||||
@ -151,17 +151,17 @@ delegate any unknown references to the parent context.
|
||||
</ul> | viewA
|
||||
```
|
||||
|
||||
Each View can have zero or more ViewPorts. By inserting and removing child Views to and from the
|
||||
ViewContainers, the application can mutate the DOM structure to any desirable state. A View may contain
|
||||
individual nodes or a complex DOM structure. The insertion points for the child Views, known as
|
||||
ViewContainers, contain a DOM element which acts as an anchor. The anchor is either a `template` or
|
||||
a `script` element depending on your browser. It is used to identify where the child Views will be
|
||||
Each View can have zero or more ViewPorts. By inserting and removing child Views to and from the
|
||||
ViewContainers, the application can mutate the DOM structure to any desirable state. A View may contain
|
||||
individual nodes or a complex DOM structure. The insertion points for the child Views, known as
|
||||
ViewContainers, contain a DOM element which acts as an anchor. The anchor is either a `template` or
|
||||
a `script` element depending on your browser. It is used to identify where the child Views will be
|
||||
inserted.
|
||||
|
||||
## Component Views
|
||||
|
||||
A View can also contain Components. Components contain Shadow DOM for encapsulating their internal
|
||||
rendering state. Unlike ViewPorts which can contain zero or more Views, the Component always contains
|
||||
A View can also contain Components. Components contain Shadow DOM for encapsulating their internal
|
||||
rendering state. Unlike ViewPorts which can contain zero or more Views, the Component always contains
|
||||
exactly one Shadow View.
|
||||
|
||||
```
|
||||
@ -205,7 +205,7 @@ And assume the following HTML View:
|
||||
</div> | viewA(greeter)
|
||||
```
|
||||
|
||||
The above UI is built using a single View, and hence a single context `greeter`. It can be expressed
|
||||
The above UI is built using a single View, and hence a single context `greeter`. It can be expressed
|
||||
in this pseudo-code.
|
||||
|
||||
```
|
||||
@ -215,15 +215,15 @@ var greeter = new Greeter();
|
||||
The View contains two bindings:
|
||||
|
||||
1. `greeting`: This is bound to the `greeting` property on the `Greeter` instance.
|
||||
2. `name.value`: This poses a problem. There is no `name` property on the `Greeter` instance. To solve
|
||||
2. `name.value`: This poses a problem. There is no `name` property on the `Greeter` instance. To solve
|
||||
this we wrap the `Greeter` instance in the `Local` instance like so:
|
||||
```
|
||||
var greeter = new Locals(new Greeter(), {name: ref_to_input_element })
|
||||
```
|
||||
|
||||
|
||||
By wrapping the `Greeter` instance into the `Locals` we allow the view to introduce variables which
|
||||
are in addition to the `Greeter` instance. During the resolution of the expressions we first check
|
||||
By wrapping the `Greeter` instance into the `Locals` we allow the view to introduce variables which
|
||||
are in addition to the `Greeter` instance. During the resolution of the expressions we first check
|
||||
the locals, and then the `Greeter` instance.
|
||||
|
||||
|
||||
@ -233,14 +233,14 @@ the locals, and then the `Greeter` instance.
|
||||
Views transition through a particular set of states:
|
||||
|
||||
1. View is created from the ProtoView.
|
||||
2. View can be attached to an existing ViewContainer.
|
||||
3. Upon attaching View to the ViewContainer the View needs to be hydrated. The hydration process
|
||||
2. View can be attached to an existing ViewContainerRef.
|
||||
3. Upon attaching View to the ViewContainerRef the View needs to be hydrated. The hydration process
|
||||
involves instantiating all of the Directives associated with the current View.
|
||||
4. At this point the view is ready and renderable. Multiple changes can be delivered to the
|
||||
4. At this point the view is ready and renderable. Multiple changes can be delivered to the
|
||||
Directives from the ChangeDetection.
|
||||
5. At some point the View can be removed. At this point all of the directives are destroyed during
|
||||
5. At some point the View can be removed. At this point all of the directives are destroyed during
|
||||
the dehydration process and the view becomes inactive.
|
||||
6. The View has to wait until it is detached from the DOM. The delay in detaching could be caused
|
||||
6. The View has to wait until it is detached from the DOM. The delay in detaching could be caused
|
||||
because an animation is animating the view away.
|
||||
7. After the View is detached from the DOM it is ready to be reused. The view reuse allows the
|
||||
7. After the View is detached from the DOM it is ready to be reused. The view reuse allows the
|
||||
application to be faster in subsequent renderings.
|
||||
|
Reference in New Issue
Block a user