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:
16
modules/angular2/src/directives/for.js
vendored
16
modules/angular2/src/directives/for.js
vendored
@ -1,6 +1,6 @@
|
||||
import {Viewport} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {Decorator} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
|
||||
import {ViewRef} from 'angular2/src/core/compiler/view_ref';
|
||||
import {ViewRef, ProtoViewRef} from 'angular2/src/core/compiler/view_ref';
|
||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
@ -36,7 +36,7 @@ import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
*
|
||||
* @exportedAs angular2/directives
|
||||
*/
|
||||
@Viewport({
|
||||
@Decorator({
|
||||
selector: '[for][of]',
|
||||
properties: {
|
||||
'iterableChanges': 'of | iterableDiff'
|
||||
@ -44,8 +44,10 @@ import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
})
|
||||
export class For {
|
||||
viewContainer: ViewContainerRef;
|
||||
constructor(viewContainer:ViewContainerRef) {
|
||||
protoViewRef: ProtoViewRef;
|
||||
constructor(viewContainer:ViewContainerRef, protoViewRef: ProtoViewRef) {
|
||||
this.viewContainer = viewContainer;
|
||||
this.protoViewRef = protoViewRef;
|
||||
}
|
||||
|
||||
set iterableChanges(changes) {
|
||||
@ -71,7 +73,7 @@ export class For {
|
||||
(addedRecord) => ListWrapper.push(insertTuples, new RecordViewTuple(addedRecord, null))
|
||||
);
|
||||
|
||||
For.bulkInsert(insertTuples, this.viewContainer);
|
||||
For.bulkInsert(insertTuples, this.viewContainer, this.protoViewRef);
|
||||
|
||||
for (var i = 0; i < insertTuples.length; i++) {
|
||||
this.perViewChange(insertTuples[i].view, insertTuples[i].record);
|
||||
@ -99,14 +101,14 @@ export class For {
|
||||
return movedTuples;
|
||||
}
|
||||
|
||||
static bulkInsert(tuples, viewContainer) {
|
||||
static bulkInsert(tuples, viewContainer, protoViewRef) {
|
||||
tuples.sort((a, b) => a.record.currentIndex - b.record.currentIndex);
|
||||
for (var i = 0; i < tuples.length; i++) {
|
||||
var tuple = tuples[i];
|
||||
if (isPresent(tuple.view)) {
|
||||
viewContainer.insert(tuple.view, tuple.record.currentIndex);
|
||||
} else {
|
||||
tuple.view = viewContainer.create(tuple.record.currentIndex);
|
||||
tuple.view = viewContainer.create(protoViewRef, tuple.record.currentIndex);
|
||||
}
|
||||
}
|
||||
return tuples;
|
||||
|
11
modules/angular2/src/directives/if.js
vendored
11
modules/angular2/src/directives/if.js
vendored
@ -1,5 +1,6 @@
|
||||
import {Viewport} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {Decorator} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
|
||||
import {ProtoViewRef} from 'angular2/src/core/compiler/view_ref';
|
||||
import {isBlank} from 'angular2/src/facade/lang';
|
||||
|
||||
/**
|
||||
@ -25,7 +26,7 @@ import {isBlank} from 'angular2/src/facade/lang';
|
||||
*
|
||||
* @exportedAs angular2/directives
|
||||
*/
|
||||
@Viewport({
|
||||
@Decorator({
|
||||
selector: '[if]',
|
||||
properties: {
|
||||
'condition': 'if'
|
||||
@ -33,17 +34,19 @@ import {isBlank} from 'angular2/src/facade/lang';
|
||||
})
|
||||
export class If {
|
||||
viewContainer: ViewContainerRef;
|
||||
protoViewRef: ProtoViewRef;
|
||||
prevCondition: boolean;
|
||||
|
||||
constructor(viewContainer: ViewContainerRef) {
|
||||
constructor(viewContainer: ViewContainerRef, protoViewRef:ProtoViewRef) {
|
||||
this.viewContainer = viewContainer;
|
||||
this.prevCondition = null;
|
||||
this.protoViewRef = protoViewRef;
|
||||
}
|
||||
|
||||
set condition(newCondition /* boolean */) {
|
||||
if (newCondition && (isBlank(this.prevCondition) || !this.prevCondition)) {
|
||||
this.prevCondition = true;
|
||||
this.viewContainer.create();
|
||||
this.viewContainer.create(this.protoViewRef);
|
||||
} else if (!newCondition && (isBlank(this.prevCondition) || this.prevCondition)) {
|
||||
this.prevCondition = false;
|
||||
this.viewContainer.clear();
|
||||
|
122
modules/angular2/src/directives/switch.js
vendored
122
modules/angular2/src/directives/switch.js
vendored
@ -1,9 +1,28 @@
|
||||
import {Decorator, Viewport} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {Decorator} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
|
||||
import {ProtoViewRef} from 'angular2/src/core/compiler/view_ref';
|
||||
import {isPresent, isBlank, normalizeBlank} from 'angular2/src/facade/lang';
|
||||
import {ListWrapper, List, MapWrapper, Map} from 'angular2/src/facade/collection';
|
||||
import {Parent} from 'angular2/src/core/annotations_impl/visibility';
|
||||
|
||||
class SwitchView {
|
||||
_viewContainerRef: ViewContainerRef;
|
||||
_protoViewRef: ProtoViewRef;
|
||||
|
||||
constructor(viewContainerRef: ViewContainerRef, protoViewRef: ProtoViewRef) {
|
||||
this._protoViewRef = protoViewRef;
|
||||
this._viewContainerRef = viewContainerRef;
|
||||
}
|
||||
|
||||
create() {
|
||||
this._viewContainerRef.create(this._protoViewRef);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this._viewContainerRef.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Switch` directive is used to conditionally swap DOM structure on your template based on a
|
||||
* scope expression.
|
||||
@ -40,93 +59,94 @@ import {Parent} from 'angular2/src/core/annotations_impl/visibility';
|
||||
export class Switch {
|
||||
_switchValue: any;
|
||||
_useDefault: boolean;
|
||||
_valueViewContainers: Map;
|
||||
_activeViewContainers: List<ViewContainerRef>;
|
||||
_valueViews: Map;
|
||||
_activeViews: List<SwitchView>;
|
||||
|
||||
constructor() {
|
||||
this._valueViewContainers = MapWrapper.create();
|
||||
this._activeViewContainers = ListWrapper.create();
|
||||
this._valueViews = MapWrapper.create();
|
||||
this._activeViews = ListWrapper.create();
|
||||
this._useDefault = false;
|
||||
}
|
||||
|
||||
set value(value) {
|
||||
// Empty the currently active ViewContainers
|
||||
this._emptyAllActiveViewContainers();
|
||||
this._emptyAllActiveViews();
|
||||
|
||||
// Add the ViewContainers matching the value (with a fallback to default)
|
||||
this._useDefault = false;
|
||||
var containers = MapWrapper.get(this._valueViewContainers, value);
|
||||
if (isBlank(containers)) {
|
||||
var views = MapWrapper.get(this._valueViews, value);
|
||||
if (isBlank(views)) {
|
||||
this._useDefault = true;
|
||||
containers = normalizeBlank(MapWrapper.get(this._valueViewContainers, _whenDefault));
|
||||
views = normalizeBlank(MapWrapper.get(this._valueViews, _whenDefault));
|
||||
}
|
||||
this._activateViewContainers(containers);
|
||||
this._activateViews(views);
|
||||
|
||||
this._switchValue = value;
|
||||
}
|
||||
|
||||
_onWhenValueChanged(oldWhen, newWhen, viewContainer: ViewContainerRef):void {
|
||||
this._deregisterViewContainer(oldWhen, viewContainer);
|
||||
this._registerViewContainer(newWhen, viewContainer);
|
||||
_onWhenValueChanged(oldWhen, newWhen, view: SwitchView):void {
|
||||
this._deregisterView(oldWhen, view);
|
||||
this._registerView(newWhen, view);
|
||||
|
||||
if (oldWhen === this._switchValue) {
|
||||
viewContainer.remove();
|
||||
ListWrapper.remove(this._activeViewContainers, viewContainer);
|
||||
view.destroy();
|
||||
ListWrapper.remove(this._activeViews, view);
|
||||
} else if (newWhen === this._switchValue) {
|
||||
if (this._useDefault) {
|
||||
this._useDefault = false;
|
||||
this._emptyAllActiveViewContainers();
|
||||
this._emptyAllActiveViews();
|
||||
}
|
||||
viewContainer.create();
|
||||
ListWrapper.push(this._activeViewContainers, viewContainer);
|
||||
view.create();
|
||||
ListWrapper.push(this._activeViews, view);
|
||||
}
|
||||
|
||||
// Switch to default when there is no more active ViewContainers
|
||||
if (this._activeViewContainers.length === 0 && !this._useDefault) {
|
||||
if (this._activeViews.length === 0 && !this._useDefault) {
|
||||
this._useDefault = true;
|
||||
this._activateViewContainers(MapWrapper.get(this._valueViewContainers, _whenDefault));
|
||||
this._activateViews(MapWrapper.get(this._valueViews, _whenDefault));
|
||||
}
|
||||
}
|
||||
|
||||
_emptyAllActiveViewContainers():void {
|
||||
var activeContainers = this._activeViewContainers;
|
||||
_emptyAllActiveViews():void {
|
||||
var activeContainers = this._activeViews;
|
||||
for (var i = 0; i < activeContainers.length; i++) {
|
||||
activeContainers[i].remove();
|
||||
activeContainers[i].destroy();
|
||||
}
|
||||
this._activeViewContainers = ListWrapper.create();
|
||||
this._activeViews = ListWrapper.create();
|
||||
}
|
||||
|
||||
_activateViewContainers(containers: List<ViewContainerRef>):void {
|
||||
// TODO(vicb): assert(this._activeViewContainers.length === 0);
|
||||
if (isPresent(containers)) {
|
||||
for (var i = 0; i < containers.length; i++) {
|
||||
containers[i].create();
|
||||
_activateViews(views: List<SwitchView>):void {
|
||||
// TODO(vicb): assert(this._activeViews.length === 0);
|
||||
if (isPresent(views)) {
|
||||
for (var i = 0; i < views.length; i++) {
|
||||
views[i].create();
|
||||
}
|
||||
this._activeViewContainers = containers;
|
||||
this._activeViews = views;
|
||||
}
|
||||
}
|
||||
|
||||
_registerViewContainer(value, container: ViewContainerRef): void {
|
||||
var containers = MapWrapper.get(this._valueViewContainers, value);
|
||||
if (isBlank(containers)) {
|
||||
containers = ListWrapper.create();
|
||||
MapWrapper.set(this._valueViewContainers, value, containers);
|
||||
_registerView(value, view: SwitchView): void {
|
||||
var views = MapWrapper.get(this._valueViews, value);
|
||||
if (isBlank(views)) {
|
||||
views = ListWrapper.create();
|
||||
MapWrapper.set(this._valueViews, value, views);
|
||||
}
|
||||
ListWrapper.push(containers, container);
|
||||
ListWrapper.push(views, view);
|
||||
}
|
||||
|
||||
_deregisterViewContainer(value, container: ViewContainerRef):void {
|
||||
_deregisterView(value, view: SwitchView):void {
|
||||
// `_whenDefault` is used a marker for non-registered whens
|
||||
if (value == _whenDefault) return;
|
||||
var containers = MapWrapper.get(this._valueViewContainers, value);
|
||||
if (containers.length == 1) {
|
||||
MapWrapper.delete(this._valueViewContainers, value);
|
||||
var views = MapWrapper.get(this._valueViews, value);
|
||||
if (views.length == 1) {
|
||||
MapWrapper.delete(this._valueViews, value);
|
||||
} else {
|
||||
ListWrapper.remove(containers, container);
|
||||
ListWrapper.remove(views, view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Defines a case statement as an expression.
|
||||
*
|
||||
@ -144,7 +164,7 @@ export class Switch {
|
||||
*
|
||||
* @exportedAs angular2/directives
|
||||
*/
|
||||
@Viewport({
|
||||
@Decorator({
|
||||
selector: '[switch-when]',
|
||||
properties: {
|
||||
'when' : 'switch-when'
|
||||
@ -153,17 +173,21 @@ export class Switch {
|
||||
export class SwitchWhen {
|
||||
_value: any;
|
||||
_switch: Switch;
|
||||
_viewContainer: ViewContainerRef;
|
||||
_view: SwitchView;
|
||||
|
||||
constructor(viewContainer: ViewContainerRef, @Parent() sswitch: Switch) {
|
||||
constructor(viewContainer: ViewContainerRef, protoViewRef: ProtoViewRef, @Parent() sswitch: Switch) {
|
||||
// `_whenDefault` is used as a marker for a not yet initialized value
|
||||
this._value = _whenDefault;
|
||||
this._switch = sswitch;
|
||||
this._viewContainer = viewContainer;
|
||||
this._view = new SwitchView(viewContainer, protoViewRef);
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
this._switch
|
||||
}
|
||||
|
||||
set when(value) {
|
||||
this._switch._onWhenValueChanged(this._value, value, this._viewContainer);
|
||||
this._switch._onWhenValueChanged(this._value, value, this._view);
|
||||
this._value = value;
|
||||
}
|
||||
}
|
||||
@ -182,12 +206,12 @@ export class SwitchWhen {
|
||||
*
|
||||
* @exportedAs angular2/directives
|
||||
*/
|
||||
@Viewport({
|
||||
@Decorator({
|
||||
selector: '[switch-default]'
|
||||
})
|
||||
export class SwitchDefault {
|
||||
constructor(viewContainer: ViewContainerRef, @Parent() sswitch: Switch) {
|
||||
sswitch._registerViewContainer(_whenDefault, viewContainer);
|
||||
constructor(viewContainer: ViewContainerRef, protoViewRef: ProtoViewRef, @Parent() sswitch: Switch) {
|
||||
sswitch._registerView(_whenDefault, new SwitchView(viewContainer, protoViewRef));
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user