refactor(compiler): remove Viewport
directives, use Decorator
instead
BREAKING_CHANGE: - The special type of `Viewport` directives is removed in favor of a more general `Decorator` directive - `ViewContainerRef` now no more has a default `ProtoViewRef` but requires an explicit one when creating views. Closes #1536
This commit is contained in:
@ -5,7 +5,7 @@ projected to DOM as well as which DOM events should invoke which methods on the
|
||||
syntax which is core to Angular and allows for data-binding, event-binding, template-instantiation.
|
||||
|
||||
The design of the template syntax has these properties:
|
||||
|
||||
|
||||
|
||||
* All data-binding expressions are easily identifiable. (i.e. there is never an ambiguity whether the value should be
|
||||
interpreted as string literal or as an expression.)
|
||||
@ -372,8 +372,8 @@ Where:
|
||||
inserted. The template can be defined implicitly with `template` attribute, which turns the current element into
|
||||
a template, or explicitly with `<template>` element. Explicit declaration is longer, but it allows for having
|
||||
templates which have more than one root DOM node.
|
||||
* `viewport` is required for templates. The Viewport directive is responsible for deciding when
|
||||
and in which order should child views be inserted into this location. An Viewport directive usually has one or
|
||||
* `viewport` is required for templates. The directive is responsible for deciding when
|
||||
and in which order should child views be inserted into this location. Such a directive usually has one or
|
||||
more bindings and can be represented as either `viewport-directive-bindings` or
|
||||
`viewport-directive-microsyntax` on `template` element or attribute. See template microsyntax for more details.
|
||||
|
||||
@ -387,7 +387,7 @@ Hello {{user}}!
|
||||
</div>
|
||||
```
|
||||
|
||||
In the above example the `if` Viewport determines whether the child view (an instance of the child template) should be
|
||||
In the above example the `if` directive determines whether the child view (an instance of the child template) should be
|
||||
inserted into the root view. The `if` makes this decision based on if the `isAdministrator` binding is true.
|
||||
|
||||
The above example is in the short form, for better clarity let's rewrite it in the canonical form, which is functionally
|
||||
@ -402,8 +402,6 @@ Hello {{user}}!
|
||||
</template>
|
||||
```
|
||||
|
||||
NOTE: Only Viewport directives can be placed on the template element. (Decorators and Components are not allowed.)
|
||||
|
||||
|
||||
### Template Microsyntax
|
||||
|
||||
@ -514,7 +512,7 @@ Where:
|
||||
* `some-element` Any element which can generate DOM events (or has an angular directive which generates the event).
|
||||
* `some-event` (escaped with `()` or `on-`) is the name of the event `some-event`. In this case the
|
||||
dash-case is converted into camel-case `someEvent`.
|
||||
* `statement` is a valid statement (as defined in section below).
|
||||
* `statement` is a valid statement (as defined in section below).
|
||||
If the execution of the statement returns `false`, then `preventDefault`is applied on the DOM event.
|
||||
|
||||
By default, angular only listens to the element on the event, and ignores events which bubble. To listen to bubbled
|
||||
|
@ -10,7 +10,6 @@ There are three different kinds of directives (described in more detail in later
|
||||
|
||||
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.
|
||||
3. *Viewport*: is responsible for adding or removing child views in a parent view. (i.e. for, if)
|
||||
|
||||
|
||||
|
||||
@ -163,21 +162,19 @@ Example of usage:
|
||||
|
||||
|
||||
|
||||
## Viewport
|
||||
## Directives that use a ViewContainer
|
||||
|
||||
Viewport is a directive which can control instantiation of child views which are then inserted into the DOM. (Examples are `if` and `for`.)
|
||||
Directives that use a ViewContainer 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 `ViewContainerRef`.
|
||||
* Viewport can insert child views into the `ViewContainerRef`. The child views show up as siblings of the `Viewport` in the DOM.
|
||||
* Every `template` element creates a `ProtoView` which can be used to create Views via the ViewContainer.
|
||||
* The child views show up as siblings of the directive in the DOM.
|
||||
|
||||
>> TODO(misko): Relationship with Injection
|
||||
>> TODO(misko): Instantiator can not be injected into child Views
|
||||
|
||||
|
||||
```
|
||||
@Viewport({
|
||||
@Directive({
|
||||
selector: '[if]',
|
||||
properties: {
|
||||
'condition': 'if'
|
||||
@ -185,17 +182,19 @@ Viewport is a directive which can control instantiation of child views which are
|
||||
})
|
||||
export class If {
|
||||
viewContainer: ViewContainerRef;
|
||||
protoViewRef: ProtoViewRef;
|
||||
view: View;
|
||||
|
||||
constructor(viewContainer: ViewContainerRef) {
|
||||
constructor(viewContainer: ViewContainerRef, protoViewRef: ProtoViewRef) {
|
||||
this.viewContainer = viewContainer;
|
||||
this.protoViewRef = protoViewRef;
|
||||
this.view = null;
|
||||
}
|
||||
|
||||
set condition(value) {
|
||||
if (value) {
|
||||
if (this.view === null) {
|
||||
this.view = this.viewContainer.create();
|
||||
this.view = this.viewContainer.create(protoViewRef);
|
||||
}
|
||||
} else {
|
||||
if (this.view !== null) {
|
||||
@ -342,7 +341,7 @@ Shadow DOM provides an encapsulation for components, so as a general rule it doe
|
||||
})
|
||||
class Kid {
|
||||
constructor(
|
||||
@Parent() dad:Dad,
|
||||
@Parent() dad:Dad,
|
||||
@Optional() grandpa:Grandpa
|
||||
) {
|
||||
this.name = 'Billy';
|
||||
@ -365,7 +364,7 @@ class Dad {
|
||||
this.dad = dad.name;
|
||||
console.log(dad)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: '[grandpa]',
|
||||
@ -379,17 +378,17 @@ class Grandpa {
|
||||
constructor() {
|
||||
this.name = 'Joe';
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Assume the following DOM structure for `grandpa.html`: The Dad has access to the Grandpa.
|
||||
```
|
||||
Name: {{name}}: <br> Children: <div dad></div>
|
||||
Name: {{name}}: <br> Children: <div dad></div>
|
||||
```
|
||||
|
||||
Assume the following DOM structure for `dad.html`: Here the rendered Kid will also have access to Grandpa.
|
||||
```
|
||||
Name: {{name}}: <br> Dad: {{dad}} <br> Children: <div kid></div>
|
||||
Name: {{name}}: <br> Dad: {{dad}} <br> Children: <div kid></div>
|
||||
```
|
||||
|
||||
## Further Reading
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
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 ViewContainerRef than can contain any number of child Views.
|
||||
A ViewContainer is location in a View which can accept child Views.
|
||||
Every ViewContainer 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
|
||||
@ -15,7 +15,7 @@ Views form a tree structure which mimics the DOM tree.
|
||||
* 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 ViewContainers. A ViewContainer 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
|
||||
creating Views.
|
||||
@ -88,7 +88,7 @@ Note:
|
||||
## Composed View
|
||||
|
||||
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.
|
||||
user. In Angular this is done by inserting child views into the ViewContainer.
|
||||
|
||||
Let's start with a View such as:
|
||||
|
||||
@ -108,7 +108,7 @@ and
|
||||
|
||||
```
|
||||
<ul> | protoViewA(someContext)
|
||||
<template></template> | protoViewA(someContext): new ProtoViewPort(protoViewB)
|
||||
<template></template> | protoViewA(someContext): protoViewB
|
||||
</ul> | protoViewA(someContext)
|
||||
```
|
||||
|
||||
@ -119,7 +119,7 @@ The next step is to compose these two ProtoViews into an actual view which is re
|
||||
|
||||
```
|
||||
<ul> | viewA(someContext)
|
||||
<template></template> | viewA(someContext): new Foreach(new ViewPort(protoViewB))
|
||||
<template></template> | viewA(someContext): new Foreach(new ViewContainer(protoViewB))
|
||||
</ul> | viewA(someContext)
|
||||
```
|
||||
|
||||
@ -128,11 +128,11 @@ has a reference to `protoViewA`).
|
||||
|
||||
|
||||
*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
|
||||
it after the `ViewContainer` anchor. This is repeated for each `person` in `people`. Notice that
|
||||
|
||||
```
|
||||
<ul> | viewA(someContext)
|
||||
<template></template> | viewA(someContext): new Foreach(new ViewPort(protoViewB))
|
||||
<template></template> | viewA(someContext): new Foreach(new ViewContainer(protoViewB))
|
||||
<li>{{person}}</li> | viewB0(locals0(someContext))
|
||||
<li>{{person}}</li> | viewB1(locals0(someContext))
|
||||
</ul> | viewA(someContext)
|
||||
@ -145,13 +145,13 @@ delegate any unknown references to the parent context.
|
||||
|
||||
```
|
||||
<ul> | viewA
|
||||
<template></template> | viewA: new Foreach(new ViewPort(protoViewB))
|
||||
<template></template> | viewA: new Foreach(new ViewContainer(protoViewB))
|
||||
<li>Alice</li> | viewB0
|
||||
<li>Bob</li> | viewB1
|
||||
</ul> | viewA
|
||||
```
|
||||
|
||||
Each View can have zero or more ViewPorts. By inserting and removing child Views to and from the
|
||||
Each View can have zero or more ViewContainers. 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
|
||||
@ -161,7 +161,7 @@ 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
|
||||
rendering state. Unlike ViewContainers which can contain zero or more Views, the Component always contains
|
||||
exactly one Shadow View.
|
||||
|
||||
```
|
||||
|
Reference in New Issue
Block a user