refactor(LifecycleEvent): remove LifecycleEvent
fixes #3924 BREAKING CHANGE The `lifecycle` configuration for directive has been dropped. Before // Dart @Component({lifecycle: const [LifecycleEvent.OnChanges], ...}) class MyComponent implements OnChanges { void onChanges() {...} } // Typescript @Component({lifecycle: [LifecycleEvent.OnChanges], ...}) class MyComponent implements OnChanges { onChanges(): void {...} } // ES5 var MyComponent = ng. Component({lifecycle: [LifecycleEvent.OnChanges], ...}). Class({ onChanges: function() {...} }); After // Dart @Component({...}) class MyComponent implements OnChanges { void onChanges() {...} } // Typescript @Component({...}) class MyComponent implements OnChanges { onChanges(): void {...} } // ES5 var MyComponent = ng .Component({...}) .Class({ onChanges: function() { } });
This commit is contained in:
parent
67b9414268
commit
8302afffb4
|
@ -14,7 +14,6 @@ export {
|
|||
ComponentMetadata,
|
||||
DirectiveMetadata,
|
||||
PipeMetadata,
|
||||
LifecycleEvent,
|
||||
ViewMetadata,
|
||||
ViewEncapsulation,
|
||||
QueryMetadata,
|
||||
|
@ -50,6 +49,8 @@ export {
|
|||
} from './src/core/metadata';
|
||||
|
||||
export {
|
||||
// todo(vbe): LifecycleHook should not be exposed (fails test.typings)
|
||||
LifecycleHook,
|
||||
AfterContentInit,
|
||||
AfterContentChecked,
|
||||
AfterViewInit,
|
||||
|
|
|
@ -1,36 +1,9 @@
|
|||
library angular2.src.core.compiler.directive_lifecycle_reflector;
|
||||
|
||||
import 'package:angular2/src/core/metadata.dart';
|
||||
import 'package:angular2/src/core/compiler/interfaces.dart';
|
||||
import 'package:angular2/src/core/reflection/reflection.dart';
|
||||
|
||||
bool hasLifecycleHook(LifecycleEvent e, type, DirectiveMetadata annotation) {
|
||||
if (annotation.lifecycle != null) {
|
||||
return annotation.lifecycle.contains(e);
|
||||
} else {
|
||||
if (type is! Type) return false;
|
||||
bool hasLifecycleHook(/*LifecycleHook*/ interface, type) {
|
||||
if (type is! Type) return false;
|
||||
|
||||
final List interfaces = reflector.interfaces(type);
|
||||
var interface;
|
||||
|
||||
if (e == LifecycleEvent.OnChanges) {
|
||||
interface = OnChanges;
|
||||
} else if (e == LifecycleEvent.OnDestroy) {
|
||||
interface = OnDestroy;
|
||||
} else if (e == LifecycleEvent.AfterContentInit) {
|
||||
interface = AfterContentInit;
|
||||
} else if (e == LifecycleEvent.AfterContentChecked) {
|
||||
interface = AfterContentChecked;
|
||||
} else if (e == LifecycleEvent.AfterViewInit) {
|
||||
interface = AfterViewInit;
|
||||
} else if (e == LifecycleEvent.AfterViewChecked) {
|
||||
interface = AfterViewChecked;
|
||||
} else if (e == LifecycleEvent.DoCheck) {
|
||||
interface = DoCheck;
|
||||
} else if (e == LifecycleEvent.OnInit) {
|
||||
interface = OnInit;
|
||||
}
|
||||
|
||||
return interfaces.contains(interface);
|
||||
}
|
||||
return reflector.interfaces(type).contains(interface);
|
||||
}
|
||||
|
|
|
@ -1,31 +1,29 @@
|
|||
import {Type, isPresent} from 'angular2/src/core/facade/lang';
|
||||
import {LifecycleEvent, DirectiveMetadata} from 'angular2/metadata';
|
||||
import {Type} from 'angular2/src/core/facade/lang';
|
||||
import * as Interfaces from './interfaces';
|
||||
|
||||
export function hasLifecycleHook(e: LifecycleEvent, type, annotation: DirectiveMetadata): boolean {
|
||||
if (isPresent(annotation.lifecycle)) {
|
||||
return annotation.lifecycle.indexOf(e) !== -1;
|
||||
} else {
|
||||
if (!(type instanceof Type)) return false;
|
||||
var proto = (<any>type).prototype;
|
||||
switch (e) {
|
||||
case LifecycleEvent.AfterContentInit:
|
||||
return !!proto.afterContentInit;
|
||||
case LifecycleEvent.AfterContentChecked:
|
||||
return !!proto.afterContentChecked;
|
||||
case LifecycleEvent.AfterViewInit:
|
||||
return !!proto.afterViewInit;
|
||||
case LifecycleEvent.AfterViewChecked:
|
||||
return !!proto.afterViewChecked;
|
||||
case LifecycleEvent.OnChanges:
|
||||
return !!proto.onChanges;
|
||||
case LifecycleEvent.DoCheck:
|
||||
return !!proto.doCheck;
|
||||
case LifecycleEvent.OnDestroy:
|
||||
return !!proto.onDestroy;
|
||||
case LifecycleEvent.OnInit:
|
||||
return !!proto.onInit;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
export function hasLifecycleHook(lcInterface: Interfaces.LifecycleHook, type): boolean {
|
||||
if (!(type instanceof Type)) return false;
|
||||
|
||||
var proto = (<any>type).prototype;
|
||||
|
||||
switch (lcInterface) {
|
||||
case Interfaces.AfterContentInit:
|
||||
return !!proto.afterContentInit;
|
||||
case Interfaces.AfterContentChecked:
|
||||
return !!proto.afterContentChecked;
|
||||
case Interfaces.AfterViewInit:
|
||||
return !!proto.afterViewInit;
|
||||
case Interfaces.AfterViewChecked:
|
||||
return !!proto.afterViewChecked;
|
||||
case Interfaces.OnChanges:
|
||||
return !!proto.onChanges;
|
||||
case Interfaces.DoCheck:
|
||||
return !!proto.doCheck;
|
||||
case Interfaces.OnDestroy:
|
||||
return !!proto.onDestroy;
|
||||
case Interfaces.OnInit:
|
||||
return !!proto.onInit;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ import * as avmModule from './view_manager';
|
|||
import {ViewContainerRef} from './view_container_ref';
|
||||
import {ElementRef} from './element_ref';
|
||||
import {TemplateRef} from './template_ref';
|
||||
import {DirectiveMetadata, ComponentMetadata, LifecycleEvent} from '../metadata/directives';
|
||||
import {DirectiveMetadata, ComponentMetadata} from '../metadata/directives';
|
||||
import {hasLifecycleHook} from './directive_lifecycle_reflector';
|
||||
import {
|
||||
ChangeDetector,
|
||||
|
@ -51,6 +51,8 @@ import {RenderDirectiveMetadata} from 'angular2/src/core/render/api';
|
|||
import {EventConfig} from 'angular2/src/core/render/event_config';
|
||||
import {PipeBinding} from '../pipes/pipe_binding';
|
||||
|
||||
import * as LifecycleHooks from './interfaces';
|
||||
|
||||
var _staticKeys;
|
||||
|
||||
export class StaticKeys {
|
||||
|
@ -160,14 +162,14 @@ export class DirectiveBinding extends ResolvedBinding {
|
|||
properties: meta.properties,
|
||||
readAttributes: DirectiveBinding._readAttributes(<any>deps),
|
||||
|
||||
callOnDestroy: hasLifecycleHook(LifecycleEvent.OnDestroy, token, meta),
|
||||
callOnChanges: hasLifecycleHook(LifecycleEvent.OnChanges, token, meta),
|
||||
callDoCheck: hasLifecycleHook(LifecycleEvent.DoCheck, token, meta),
|
||||
callOnInit: hasLifecycleHook(LifecycleEvent.OnInit, token, meta),
|
||||
callAfterContentInit: hasLifecycleHook(LifecycleEvent.AfterContentInit, token, meta),
|
||||
callAfterContentChecked: hasLifecycleHook(LifecycleEvent.AfterContentChecked, token, meta),
|
||||
callAfterViewInit: hasLifecycleHook(LifecycleEvent.AfterViewInit, token, meta),
|
||||
callAfterViewChecked: hasLifecycleHook(LifecycleEvent.AfterViewChecked, token, meta),
|
||||
callOnDestroy: hasLifecycleHook(LifecycleHooks.OnDestroy, token),
|
||||
callOnChanges: hasLifecycleHook(LifecycleHooks.OnChanges, token),
|
||||
callDoCheck: hasLifecycleHook(LifecycleHooks.DoCheck, token),
|
||||
callOnInit: hasLifecycleHook(LifecycleHooks.OnInit, token),
|
||||
callAfterContentInit: hasLifecycleHook(LifecycleHooks.AfterContentInit, token),
|
||||
callAfterContentChecked: hasLifecycleHook(LifecycleHooks.AfterContentChecked, token),
|
||||
callAfterViewInit: hasLifecycleHook(LifecycleHooks.AfterViewInit, token),
|
||||
callAfterViewChecked: hasLifecycleHook(LifecycleHooks.AfterViewChecked, token),
|
||||
|
||||
changeDetection: meta instanceof ComponentMetadata ? meta.changeDetection : null,
|
||||
|
||||
|
|
|
@ -1,58 +1,181 @@
|
|||
import {StringMap} from 'angular2/src/core/facade/collection';
|
||||
import {global} from 'angular2/src/core/facade/lang';
|
||||
|
||||
// This is here only so that after TS transpilation the file is not empty.
|
||||
// TODO(rado): find a better way to fix this, or remove if likely culprit
|
||||
// https://github.com/systemjs/systemjs/issues/487 gets closed.
|
||||
var __ignore_me = global;
|
||||
/**
|
||||
* Defines lifecycle method {@link metadata/LifeCycleEvent#OnChanges `LifeCycleEvent.OnChanges`}
|
||||
* called after all of component's bound properties are updated.
|
||||
*/
|
||||
export interface OnChanges { onChanges(changes: StringMap<string, any>): void; }
|
||||
|
||||
/**
|
||||
* Defines lifecycle method {@link metadata/LifeCycleEvent#OnInit `LifeCycleEvent.OnInit`}
|
||||
* called when a directive is being checked the first time.
|
||||
* Lifecycle hooks are guaranteed to be called in the following order:
|
||||
* - `OnChanges` (if any bindings have changed),
|
||||
* - `OnInit` (after the first check only),
|
||||
* - `DoCheck`,
|
||||
* - `AfterContentInit`,
|
||||
* - `AfterContentChecked`,
|
||||
* - `OnDestroy` (at the very end before destruction)
|
||||
*
|
||||
* // todo(vicb): describe Dart & TS vs JS
|
||||
*/
|
||||
export interface OnInit { onInit(): void; }
|
||||
export interface LifecycleHook {}
|
||||
|
||||
/**
|
||||
* Defines lifecycle method {@link metadata/LifeCycleEvent#DoCheck `LifeCycleEvent.DoCheck`}
|
||||
* called when a directive is being checked.
|
||||
* Notify a directive when any of its bindings have changed.
|
||||
*
|
||||
* `onChanges` is called right after the directive's bindings have been checked,
|
||||
* and before any of its children's bindings have been checked.
|
||||
*
|
||||
* It is invoked only if at least one of the directive's bindings has changed.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* ```
|
||||
* @Component(...)
|
||||
* class MyComponent implements OnChanges {
|
||||
* propA;
|
||||
* propB;
|
||||
*
|
||||
* onChanges(changes: {[idx: string, PropertyUpdate]}): void {
|
||||
* // This will get called after any of the properties have been updated.
|
||||
* if (changes['propA']) {
|
||||
* // if propA was updated
|
||||
* }
|
||||
* if (changes['propA']) {
|
||||
* // if propB was updated
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export interface DoCheck { doCheck(): boolean; }
|
||||
export class OnChanges implements LifecycleHook {
|
||||
onChanges(changes: StringMap<string, any>): void {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines lifecycle method {@link metadata/LifeCycleEvent#OnDestroy `LifeCycleEvent.OnDestroy`}
|
||||
* called when a directive is being destroyed.
|
||||
* Notify a directive when it has been checked the first time.
|
||||
*
|
||||
* `onInit` is called right after the directive's bindings have been checked for the first time,
|
||||
* and before any of its children's bindings have been checked.
|
||||
*
|
||||
* It is invoked only once.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```
|
||||
* @Component(...)
|
||||
* class MyComponent @implements OnInit {
|
||||
* onInit(): void {
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export interface OnDestroy { onDestroy(): void; }
|
||||
export class OnInit implements LifecycleHook {
|
||||
onInit(): void {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines lifecycle method
|
||||
* {@link metadata/LifeCycleEvent#AfterContentInit `LifeCycleEvent.afterContentInit`}
|
||||
* called when the bindings of all its content children have been checked the first time.
|
||||
* Overrides the default change detection.
|
||||
*
|
||||
* `doCheck()` gets called to check the changes in the directives instead of the default
|
||||
* change detection mechanism.
|
||||
*
|
||||
* It is invoked every time the change detection is triggered.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```
|
||||
* @Component(...)
|
||||
* class MyComponent implements DoCheck {
|
||||
* doCheck(): void {
|
||||
* // Custom logic to detect changes
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export interface AfterContentInit { afterContentInit(): void; }
|
||||
export class DoCheck implements LifecycleHook {
|
||||
doCheck(): void {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines lifecycle method
|
||||
* {@link metadata/LifeCycleEvent#AfterContentChecked `LifeCycleEvent.afterContentChecked`}
|
||||
* called when the bindings of all its content children have been checked.
|
||||
* Notify a directive whenever a {@link ViewMetadata} that contains it is destroyed.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```
|
||||
* @Component(...)
|
||||
* class MyComponent implements OnDestroy {
|
||||
* onDestroy(): void {
|
||||
* // invoked to notify directive of the containing view destruction.
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export interface AfterContentChecked { afterContentChecked(): void; }
|
||||
export class OnDestroy implements LifecycleHook {
|
||||
onDestroy(): void {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines lifecycle method
|
||||
* {@link metadata/LifeCycleEvent#AfterViewInit `LifeCycleEvent.afterViewInit`}
|
||||
* called when the bindings of all its view children have been checked the first time.
|
||||
* Notify a directive when the bindings of all its content children have been checked the first
|
||||
* time (whether they have changed or not).
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```
|
||||
* @Component(...)
|
||||
* class MyComponent implements AfterContentInit {
|
||||
* afterContentInit(): void {
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export interface AfterViewInit { afterViewInit(): void; }
|
||||
export class AfterContentInit implements LifecycleHook {
|
||||
afterContentInit(): void {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines lifecycle method
|
||||
* {@link metadata/LifeCycleEvent#AfterViewChecked `LifeCycleEvent.afterViewChecked`}
|
||||
* called when the bindings of all its view children have been checked.
|
||||
* Notify a directive when the bindings of all its content children have been checked (whether
|
||||
* they have changed or not).
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```
|
||||
* @Component(...)
|
||||
* class MyComponent implements AfterContentChecked {
|
||||
* afterContentChecked(): void {
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export interface AfterViewChecked { afterViewChecked(): void; }
|
||||
export class AfterContentChecked implements LifecycleHook {
|
||||
afterContentChecked(): void {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify a directive when the bindings of all its view children have been checked the first time
|
||||
* (whether they have changed or not).
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```
|
||||
* @Component(...)
|
||||
* class MyComponent implements AfterViewInit {
|
||||
* afterViewInit(): void {
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export class AfterViewInit implements LifecycleHook {
|
||||
afterViewInit(): void {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify a directive when the bindings of all its view children have been checked (whether they
|
||||
* have changed or not).
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```
|
||||
* @Component(...)
|
||||
* class MyComponent implements AfterViewChecked {
|
||||
* afterViewChecked(): void {
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export class AfterViewChecked implements LifecycleHook {
|
||||
afterViewChecked(): void {}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {isPresent, isString, StringWrapper, isBlank} from 'angular2/src/core/facade/lang';
|
||||
import {Directive, LifecycleEvent} from 'angular2/metadata';
|
||||
import {Directive, DoCheck, OnDestroy} from 'angular2/metadata';
|
||||
import {ElementRef} from 'angular2/core';
|
||||
import {Renderer} from 'angular2/src/core/render/api';
|
||||
import {
|
||||
|
@ -34,12 +34,8 @@ import {
|
|||
* </div>
|
||||
* ```
|
||||
*/
|
||||
@Directive({
|
||||
selector: '[ng-class]',
|
||||
lifecycle: [LifecycleEvent.DoCheck, LifecycleEvent.OnDestroy],
|
||||
properties: ['rawClass: ng-class', 'initialClasses: class']
|
||||
})
|
||||
export class NgClass {
|
||||
@Directive({selector: '[ng-class]', properties: ['rawClass: ng-class', 'initialClasses: class']})
|
||||
export class NgClass implements DoCheck, OnDestroy {
|
||||
private _differ: any;
|
||||
private _mode: string;
|
||||
private _initialClasses = [];
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Directive, LifecycleEvent} from 'angular2/metadata';
|
||||
import {Directive, DoCheck} from 'angular2/metadata';
|
||||
import {ViewContainerRef, ViewRef, TemplateRef} from 'angular2/core';
|
||||
import {ChangeDetectorRef, IterableDiffer, IterableDiffers} from 'angular2/change_detection';
|
||||
import {isPresent, isBlank} from 'angular2/src/core/facade/lang';
|
||||
|
@ -34,9 +34,8 @@ import {isPresent, isBlank} from 'angular2/src/core/facade/lang';
|
|||
* - `<li template="ng-for #item of items; #i = index">...</li>`
|
||||
* - `<template ng-for #item [ng-for-of]="items" #i="index"><li>...</li></template>`
|
||||
*/
|
||||
@Directive(
|
||||
{selector: '[ng-for][ng-for-of]', properties: ['ngForOf'], lifecycle: [LifecycleEvent.DoCheck]})
|
||||
export class NgFor {
|
||||
@Directive({selector: '[ng-for][ng-for-of]', properties: ['ngForOf']})
|
||||
export class NgFor implements DoCheck {
|
||||
_ngForOf: any;
|
||||
private _differ: IterableDiffer;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Directive, LifecycleEvent} from 'angular2/metadata';
|
||||
import {Directive, DoCheck} from 'angular2/metadata';
|
||||
import {ElementRef} from 'angular2/core';
|
||||
import {KeyValueDiffer, KeyValueDiffers} from 'angular2/change_detection';
|
||||
import {isPresent, isBlank, print} from 'angular2/src/core/facade/lang';
|
||||
|
@ -25,12 +25,8 @@ import {Renderer} from 'angular2/src/core/render/api';
|
|||
* - `<div [ng-style]="{'text-align': alignExp}"></div>`
|
||||
* - `<div [ng-style]="styleExp"></div>`
|
||||
*/
|
||||
@Directive({
|
||||
selector: '[ng-style]',
|
||||
lifecycle: [LifecycleEvent.DoCheck],
|
||||
properties: ['rawStyle: ng-style']
|
||||
})
|
||||
export class NgStyle {
|
||||
@Directive({selector: '[ng-style]', properties: ['rawStyle: ng-style']})
|
||||
export class NgStyle implements DoCheck {
|
||||
_rawStyle;
|
||||
_differ: KeyValueDiffer;
|
||||
|
||||
|
|
|
@ -16,14 +16,13 @@ export "./metadata/view.dart";
|
|||
class Directive extends DirectiveMetadata {
|
||||
const Directive({String selector, List<String> properties,
|
||||
List<String> events, Map<String, String> host,
|
||||
List<LifecycleEvent> lifecycle, List bindings, String exportAs,
|
||||
List bindings, String exportAs,
|
||||
bool compileChildren: true})
|
||||
: super(
|
||||
selector: selector,
|
||||
properties: properties,
|
||||
events: events,
|
||||
host: host,
|
||||
lifecycle: lifecycle,
|
||||
bindings: bindings,
|
||||
exportAs: exportAs,
|
||||
compileChildren: compileChildren);
|
||||
|
@ -35,14 +34,13 @@ class Directive extends DirectiveMetadata {
|
|||
class Component extends ComponentMetadata {
|
||||
const Component({String selector, List<String> properties,
|
||||
List<String> events, Map<String, String> host,
|
||||
List<LifecycleEvent> lifecycle, List bindings, String exportAs,
|
||||
List bindings, String exportAs,
|
||||
bool compileChildren, List viewBindings, ChangeDetectionStrategy changeDetection})
|
||||
: super(
|
||||
selector: selector,
|
||||
properties: properties,
|
||||
events: events,
|
||||
host: host,
|
||||
lifecycle: lifecycle,
|
||||
bindings: bindings,
|
||||
exportAs: exportAs,
|
||||
compileChildren: compileChildren,
|
||||
|
|
|
@ -13,7 +13,6 @@ export {
|
|||
ComponentMetadata,
|
||||
DirectiveMetadata,
|
||||
PipeMetadata,
|
||||
LifecycleEvent,
|
||||
PropertyMetadata,
|
||||
EventMetadata,
|
||||
HostBindingMetadata,
|
||||
|
@ -33,7 +32,6 @@ import {
|
|||
ComponentMetadata,
|
||||
DirectiveMetadata,
|
||||
PipeMetadata,
|
||||
LifecycleEvent,
|
||||
PropertyMetadata,
|
||||
EventMetadata,
|
||||
HostBindingMetadata,
|
||||
|
@ -142,13 +140,11 @@ export interface ViewDecorator extends TypeDecorator {
|
|||
export interface DirectiveFactory {
|
||||
(obj: {
|
||||
selector?: string, properties?: string[], events?: string[], host?: StringMap<string, string>,
|
||||
lifecycle?: LifecycleEvent[], bindings?: any[], exportAs?: string,
|
||||
compileChildren?: boolean;
|
||||
bindings?: any[], exportAs?: string, compileChildren?: boolean;
|
||||
}): DirectiveDecorator;
|
||||
new (obj: {
|
||||
selector?: string, properties?: string[], events?: string[], host?: StringMap<string, string>,
|
||||
lifecycle?: LifecycleEvent[], bindings?: any[], exportAs?: string,
|
||||
compileChildren?: boolean;
|
||||
bindings?: any[], exportAs?: string, compileChildren?: boolean;
|
||||
}): DirectiveMetadata;
|
||||
}
|
||||
|
||||
|
@ -201,7 +197,6 @@ export interface ComponentFactory {
|
|||
properties?: string[],
|
||||
events?: string[],
|
||||
host?: StringMap<string, string>,
|
||||
lifecycle?: LifecycleEvent[],
|
||||
bindings?: any[],
|
||||
exportAs?: string,
|
||||
compileChildren?: boolean,
|
||||
|
@ -213,7 +208,6 @@ export interface ComponentFactory {
|
|||
properties?: string[],
|
||||
events?: string[],
|
||||
host?: StringMap<string, string>,
|
||||
lifecycle?: LifecycleEvent[],
|
||||
bindings?: any[],
|
||||
exportAs?: string,
|
||||
compileChildren?: boolean,
|
||||
|
@ -545,4 +539,4 @@ export var HostBinding: HostBindingFactory = makePropDecorator(HostBindingMetada
|
|||
/**
|
||||
* {@link HostListenerMetadata} factory function.
|
||||
*/
|
||||
export var HostListener: HostListenerFactory = makePropDecorator(HostListenerMetadata);
|
||||
export var HostListener: HostListenerFactory = makePropDecorator(HostListenerMetadata);
|
||||
|
|
|
@ -630,13 +630,6 @@ export class DirectiveMetadata extends InjectableMetadata {
|
|||
*/
|
||||
host: StringMap<string, string>;
|
||||
|
||||
/**
|
||||
* Specifies which lifecycle should be notified to the directive.
|
||||
*
|
||||
* See {@link LifecycleEvent} for details.
|
||||
*/
|
||||
lifecycle: LifecycleEvent[];
|
||||
|
||||
/**
|
||||
* If set to false the compiler does not compile the children of this directive.
|
||||
*/
|
||||
|
@ -703,14 +696,12 @@ export class DirectiveMetadata extends InjectableMetadata {
|
|||
exportAs: string;
|
||||
|
||||
constructor({
|
||||
selector, properties, events, host, lifecycle, bindings, exportAs,
|
||||
compileChildren = true,
|
||||
selector, properties, events, host, bindings, exportAs, compileChildren = true,
|
||||
}: {
|
||||
selector?: string,
|
||||
properties?: string[],
|
||||
events?: string[],
|
||||
host?: StringMap<string, string>,
|
||||
lifecycle?: LifecycleEvent[],
|
||||
bindings?: any[],
|
||||
exportAs?: string,
|
||||
compileChildren?: boolean,
|
||||
|
@ -721,7 +712,6 @@ export class DirectiveMetadata extends InjectableMetadata {
|
|||
this.events = events;
|
||||
this.host = host;
|
||||
this.exportAs = exportAs;
|
||||
this.lifecycle = lifecycle;
|
||||
this.compileChildren = compileChildren;
|
||||
this.bindings = bindings;
|
||||
}
|
||||
|
@ -818,13 +808,12 @@ export class ComponentMetadata extends DirectiveMetadata {
|
|||
*/
|
||||
viewBindings: any[];
|
||||
|
||||
constructor({selector, properties, events, host, exportAs, lifecycle, bindings, viewBindings,
|
||||
constructor({selector, properties, events, host, exportAs, bindings, viewBindings,
|
||||
changeDetection = ChangeDetectionStrategy.Default, compileChildren = true}: {
|
||||
selector?: string,
|
||||
properties?: string[],
|
||||
events?: string[],
|
||||
host?: StringMap<string, string>,
|
||||
lifecycle?: LifecycleEvent[],
|
||||
bindings?: any[],
|
||||
exportAs?: string,
|
||||
compileChildren?: boolean,
|
||||
|
@ -838,7 +827,6 @@ export class ComponentMetadata extends DirectiveMetadata {
|
|||
host: host,
|
||||
exportAs: exportAs,
|
||||
bindings: bindings,
|
||||
lifecycle: lifecycle,
|
||||
compileChildren: compileChildren
|
||||
});
|
||||
|
||||
|
@ -847,206 +835,6 @@ export class ComponentMetadata extends DirectiveMetadata {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lifecycle events are guaranteed to be called in the following order:
|
||||
* - `OnChanges` (if any bindings have changed),
|
||||
* - `OnInit` (after the first check only),
|
||||
* - `DoCheck`,
|
||||
* - `AfterContentChecked`
|
||||
* - `AfterContentChecked`
|
||||
* - `OnDestroy` (at the very end before destruction)
|
||||
*/
|
||||
export enum LifecycleEvent {
|
||||
/**
|
||||
* Notify a directive when it has been checked the first time.
|
||||
*
|
||||
* This method is called right after the directive's bindings have been checked,
|
||||
* and before any of its children's bindings have been checked.
|
||||
*
|
||||
* It is invoked only once.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```
|
||||
* @Directive({
|
||||
* selector: '[class-set]',
|
||||
* lifecycle: [LifecycleEvent.OnInit]
|
||||
* })
|
||||
* class ClassSet {
|
||||
* onInit() {
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
OnInit,
|
||||
|
||||
/**
|
||||
* Notify a directive whenever a {@link ViewMetadata} that contains it is destroyed.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```
|
||||
* @Directive({
|
||||
* ...,
|
||||
* lifecycle: [LifecycleEvent.OnDestroy]
|
||||
* })
|
||||
* class ClassSet {
|
||||
* onDestroy() {
|
||||
* // invoked to notify directive of the containing view destruction.
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
OnDestroy,
|
||||
|
||||
|
||||
/**
|
||||
* Notify a directive when any of its bindings have changed.
|
||||
*
|
||||
* This method is called right after the directive's bindings have been checked,
|
||||
* and before any of its children's bindings have been checked.
|
||||
*
|
||||
* It is invoked only if at least one of the directive's bindings has changed.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* ```
|
||||
* @Directive({
|
||||
* selector: '[class-set]',
|
||||
* properties: [
|
||||
* 'propA',
|
||||
* 'propB'
|
||||
* ],
|
||||
* lifecycle: [LifecycleEvent.OnChanges]
|
||||
* })
|
||||
* class ClassSet {
|
||||
* propA;
|
||||
* propB;
|
||||
* onChanges(changes:{[idx: string, PropertyUpdate]}) {
|
||||
* // This will get called after any of the properties have been updated.
|
||||
* if (changes['propA']) {
|
||||
* // if propA was updated
|
||||
* }
|
||||
* if (changes['propA']) {
|
||||
* // if propB was updated
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
OnChanges,
|
||||
|
||||
/**
|
||||
* Notify a directive when it has been checked.
|
||||
*
|
||||
* This method is called right after the directive's bindings have been checked,
|
||||
* and before any of its children's bindings have been checked.
|
||||
*
|
||||
* It is invoked every time even when none of the directive's bindings has changed.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```
|
||||
* @Directive({
|
||||
* selector: '[class-set]',
|
||||
* lifecycle: [LifecycleEvent.DoCheck]
|
||||
* })
|
||||
* class ClassSet {
|
||||
* doCheck() {
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
DoCheck,
|
||||
|
||||
/**
|
||||
* Notify a directive when the bindings of all its content children have been checked the first
|
||||
* time (whether they
|
||||
* have changed or not).
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```
|
||||
* @Directive({
|
||||
* selector: '[class-set]',
|
||||
* lifecycle: [LifecycleEvent.AfterContentInit]
|
||||
* })
|
||||
* class ClassSet {
|
||||
*
|
||||
* afterContentInit() {
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
AfterContentInit,
|
||||
|
||||
/**
|
||||
* Notify a directive when the bindings of all its content children have been checked (whether
|
||||
* they
|
||||
* have changed or not).
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```
|
||||
* @Directive({
|
||||
* selector: '[class-set]',
|
||||
* lifecycle: [LifecycleEvent.AfterContentChecked]
|
||||
* })
|
||||
* class ClassSet {
|
||||
*
|
||||
* afterContentChecked() {
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
AfterContentChecked,
|
||||
|
||||
/**
|
||||
* Notify a directive when the bindings of all its view children have been checked the first time
|
||||
* (whether they
|
||||
* have changed or not).
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```
|
||||
* @Directive({
|
||||
* selector: '[class-set]',
|
||||
* lifecycle: [LifecycleEvent.AfterViewInit]
|
||||
* })
|
||||
* class ClassSet {
|
||||
*
|
||||
* afterViewInit() {
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
AfterViewInit,
|
||||
|
||||
/**
|
||||
* Notify a directive when the bindings of all its view children have been checked (whether they
|
||||
* have changed or not).
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```
|
||||
* @Directive({
|
||||
* selector: '[class-set]',
|
||||
* lifecycle: [LifecycleEvent.AfterViewChecked]
|
||||
* })
|
||||
* class ClassSet {
|
||||
*
|
||||
* afterViewChecked() {
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
AfterViewChecked
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare reusable pipe function.
|
||||
*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Directive, LifecycleEvent} from 'angular2/metadata';
|
||||
import {Directive, OnInit, OnDestroy} from 'angular2/metadata';
|
||||
import {Inject, Host, SkipSelf, forwardRef, Binding} from 'angular2/di';
|
||||
import {ListWrapper} from 'angular2/src/core/facade/collection';
|
||||
import {CONST_EXPR} from 'angular2/src/core/facade/lang';
|
||||
|
@ -52,10 +52,10 @@ const controlGroupBinding =
|
|||
selector: '[ng-control-group]',
|
||||
bindings: [controlGroupBinding],
|
||||
properties: ['name: ng-control-group'],
|
||||
lifecycle: [LifecycleEvent.OnInit, LifecycleEvent.OnDestroy],
|
||||
exportAs: 'form'
|
||||
})
|
||||
export class NgControlGroup extends ControlContainer {
|
||||
export class NgControlGroup extends ControlContainer implements OnInit,
|
||||
OnDestroy {
|
||||
_parent: ControlContainer;
|
||||
constructor(@Host() @SkipSelf() _parent: ControlContainer) {
|
||||
super();
|
||||
|
|
|
@ -2,7 +2,7 @@ import {CONST_EXPR} from 'angular2/src/core/facade/lang';
|
|||
import {EventEmitter, ObservableWrapper} from 'angular2/src/core/facade/async';
|
||||
import {StringMap} from 'angular2/src/core/facade/collection';
|
||||
|
||||
import {Query, Directive, LifecycleEvent} from 'angular2/metadata';
|
||||
import {Query, Directive, OnChanges, OnDestroy} from 'angular2/metadata';
|
||||
import {forwardRef, Host, SkipSelf, Binding, Inject, Optional} from 'angular2/di';
|
||||
|
||||
import {ControlContainer} from './control_container';
|
||||
|
@ -76,10 +76,10 @@ const controlNameBinding =
|
|||
bindings: [controlNameBinding],
|
||||
properties: ['name: ngControl', 'model: ngModel'],
|
||||
events: ['update: ngModel'],
|
||||
lifecycle: [LifecycleEvent.OnDestroy, LifecycleEvent.OnChanges],
|
||||
exportAs: 'form'
|
||||
})
|
||||
export class NgControlName extends NgControl {
|
||||
export class NgControlName extends NgControl implements OnChanges,
|
||||
OnDestroy {
|
||||
_parent: ControlContainer;
|
||||
update = new EventEmitter();
|
||||
model: any;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {CONST_EXPR} from 'angular2/src/core/facade/lang';
|
||||
import {EventEmitter, ObservableWrapper} from 'angular2/src/core/facade/async';
|
||||
|
||||
import {Query, Directive, LifecycleEvent} from 'angular2/metadata';
|
||||
import {Query, Directive, OnChanges} from 'angular2/metadata';
|
||||
import {forwardRef, Binding, Inject, Optional} from 'angular2/di';
|
||||
|
||||
import {NgControl} from './ng_control';
|
||||
|
@ -62,10 +62,9 @@ const formControlBinding =
|
|||
bindings: [formControlBinding],
|
||||
properties: ['form: ngFormControl', 'model: ngModel'],
|
||||
events: ['update: ngModel'],
|
||||
lifecycle: [LifecycleEvent.OnChanges],
|
||||
exportAs: 'form'
|
||||
})
|
||||
export class NgFormControl extends NgControl {
|
||||
export class NgFormControl extends NgControl implements OnChanges {
|
||||
form: Control;
|
||||
update = new EventEmitter();
|
||||
_added = false;
|
||||
|
|
|
@ -2,7 +2,7 @@ import {CONST_EXPR} from 'angular2/src/core/facade/lang';
|
|||
import {ListWrapper} from 'angular2/src/core/facade/collection';
|
||||
import {ObservableWrapper, EventEmitter} from 'angular2/src/core/facade/async';
|
||||
|
||||
import {Directive, LifecycleEvent} from 'angular2/metadata';
|
||||
import {Directive, OnChanges} from 'angular2/metadata';
|
||||
import {forwardRef, Binding} from 'angular2/di';
|
||||
import {NgControl} from './ng_control';
|
||||
import {NgControlGroup} from './ng_control_group';
|
||||
|
@ -84,14 +84,14 @@ const formDirectiveBinding =
|
|||
selector: '[ng-form-model]',
|
||||
bindings: [formDirectiveBinding],
|
||||
properties: ['form: ng-form-model'],
|
||||
lifecycle: [LifecycleEvent.OnChanges],
|
||||
host: {
|
||||
'(submit)': 'onSubmit()',
|
||||
},
|
||||
events: ['ngSubmit'],
|
||||
exportAs: 'form'
|
||||
})
|
||||
export class NgFormModel extends ControlContainer implements Form {
|
||||
export class NgFormModel extends ControlContainer implements Form,
|
||||
OnChanges {
|
||||
form: ControlGroup = null;
|
||||
directives: NgControl[] = [];
|
||||
ngSubmit = new EventEmitter();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {CONST_EXPR} from 'angular2/src/core/facade/lang';
|
||||
import {EventEmitter, ObservableWrapper} from 'angular2/src/core/facade/async';
|
||||
|
||||
import {Query, Directive, LifecycleEvent} from 'angular2/metadata';
|
||||
import {Query, Directive, OnChanges} from 'angular2/metadata';
|
||||
import {forwardRef, Binding, Inject, Optional} from 'angular2/di';
|
||||
|
||||
import {NgControl} from './ng_control';
|
||||
|
@ -32,10 +32,9 @@ const formControlBinding = CONST_EXPR(new Binding(NgControl, {toAlias: forwardRe
|
|||
bindings: [formControlBinding],
|
||||
properties: ['model: ngModel'],
|
||||
events: ['update: ngModel'],
|
||||
lifecycle: [LifecycleEvent.OnChanges],
|
||||
exportAs: 'form'
|
||||
})
|
||||
export class NgModel extends NgControl {
|
||||
export class NgModel extends NgControl implements OnChanges {
|
||||
_control = new Control();
|
||||
_added = false;
|
||||
update = new EventEmitter();
|
||||
|
|
|
@ -16,22 +16,10 @@ main() {
|
|||
.callOnChanges).toBe(true);
|
||||
});
|
||||
|
||||
it("should be true when the lifecycle includes onChanges", () {
|
||||
expect(metadata(DirectiveNoHooks,
|
||||
new Directive(lifecycle: [LifecycleEvent.OnChanges]))
|
||||
.callOnChanges).toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () {
|
||||
expect(metadata(DirectiveNoHooks, new Directive()).callOnChanges)
|
||||
.toBe(false);
|
||||
});
|
||||
|
||||
it("should be false when empty lifecycle", () {
|
||||
expect(metadata(
|
||||
DirectiveImplementingOnChanges, new Directive(lifecycle: []))
|
||||
.callOnChanges).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("onDestroy", () {
|
||||
|
@ -40,12 +28,6 @@ main() {
|
|||
.callOnDestroy).toBe(true);
|
||||
});
|
||||
|
||||
it("should be true when the lifecycle includes onDestroy", () {
|
||||
expect(metadata(DirectiveNoHooks,
|
||||
new Directive(lifecycle: [LifecycleEvent.OnDestroy]))
|
||||
.callOnDestroy).toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () {
|
||||
expect(metadata(DirectiveNoHooks, new Directive()).callOnDestroy)
|
||||
.toBe(false);
|
||||
|
@ -58,12 +40,6 @@ main() {
|
|||
.callDoCheck).toBe(true);
|
||||
});
|
||||
|
||||
it("should be true when the lifecycle includes doCheck", () {
|
||||
expect(metadata(DirectiveNoHooks,
|
||||
new Directive(lifecycle: [LifecycleEvent.DoCheck]))
|
||||
.callDoCheck).toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () {
|
||||
expect(metadata(DirectiveNoHooks, new Directive()).callDoCheck)
|
||||
.toBe(false);
|
||||
|
@ -76,12 +52,6 @@ main() {
|
|||
.callOnInit).toBe(true);
|
||||
});
|
||||
|
||||
it("should be true when the lifecycle includes onInit", () {
|
||||
expect(metadata(DirectiveNoHooks,
|
||||
new Directive(lifecycle: [LifecycleEvent.OnInit])).callOnInit)
|
||||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () {
|
||||
expect(metadata(DirectiveNoHooks, new Directive()).callOnInit)
|
||||
.toBe(false);
|
||||
|
@ -95,12 +65,6 @@ main() {
|
|||
.callAfterContentInit).toBe(true);
|
||||
});
|
||||
|
||||
it("should be true when the lifecycle includes afterContentInit", () {
|
||||
expect(metadata(DirectiveNoHooks,
|
||||
new Directive(lifecycle: [LifecycleEvent.AfterContentInit]))
|
||||
.callAfterContentInit).toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () {
|
||||
expect(metadata(DirectiveNoHooks, new Directive())
|
||||
.callAfterContentInit).toBe(false);
|
||||
|
@ -114,12 +78,6 @@ main() {
|
|||
.callAfterContentChecked).toBe(true);
|
||||
});
|
||||
|
||||
it("should be true when the lifecycle includes afterContentChecked", () {
|
||||
expect(metadata(DirectiveNoHooks,
|
||||
new Directive(lifecycle: [LifecycleEvent.AfterContentChecked]))
|
||||
.callAfterContentChecked).toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () {
|
||||
expect(metadata(DirectiveNoHooks, new Directive())
|
||||
.callAfterContentChecked).toBe(false);
|
||||
|
@ -133,12 +91,6 @@ main() {
|
|||
.callAfterViewInit).toBe(true);
|
||||
});
|
||||
|
||||
it("should be true when the lifecycle includes afterViewInit", () {
|
||||
expect(metadata(DirectiveNoHooks,
|
||||
new Directive(lifecycle: [LifecycleEvent.AfterViewInit]))
|
||||
.callAfterViewInit).toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () {
|
||||
expect(metadata(DirectiveNoHooks, new Directive())
|
||||
.callAfterViewInit).toBe(false);
|
||||
|
@ -152,12 +104,6 @@ main() {
|
|||
.callAfterViewChecked).toBe(true);
|
||||
});
|
||||
|
||||
it("should be true when the lifecycle includes afterViewChecked", () {
|
||||
expect(metadata(DirectiveNoHooks,
|
||||
new Directive(lifecycle: [LifecycleEvent.AfterViewChecked]))
|
||||
.callAfterViewChecked).toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () {
|
||||
expect(metadata(DirectiveNoHooks, new Directive())
|
||||
.callAfterViewChecked).toBe(false);
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
proxy
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {DirectiveMetadata, LifecycleEvent} from 'angular2/src/core/metadata';
|
||||
import {DirectiveMetadata} from 'angular2/src/core/metadata';
|
||||
import {DirectiveBinding} from 'angular2/src/core/compiler/element_injector';
|
||||
import {RenderDirectiveMetadata} from 'angular2/src/core/render/api';
|
||||
|
||||
|
@ -30,22 +30,9 @@ export function main() {
|
|||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be true when the lifecycle includes onChanges", () => {
|
||||
expect(metadata(DirectiveNoHooks,
|
||||
new DirectiveMetadata({lifecycle: [LifecycleEvent.OnChanges]}))
|
||||
.callOnChanges)
|
||||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () => {
|
||||
expect(metadata(DirectiveNoHooks, new DirectiveMetadata()).callOnChanges).toBe(false);
|
||||
});
|
||||
|
||||
it("should be false when empty lifecycle", () => {
|
||||
expect(metadata(DirectiveWithOnChangesMethod, new DirectiveMetadata({lifecycle: []}))
|
||||
.callOnChanges)
|
||||
.toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("onDestroy", () => {
|
||||
|
@ -54,13 +41,6 @@ export function main() {
|
|||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be true when the lifecycle includes onDestroy", () => {
|
||||
expect(metadata(DirectiveNoHooks,
|
||||
new DirectiveMetadata({lifecycle: [LifecycleEvent.OnDestroy]}))
|
||||
.callOnDestroy)
|
||||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () => {
|
||||
expect(metadata(DirectiveNoHooks, new DirectiveMetadata()).callOnDestroy).toBe(false);
|
||||
});
|
||||
|
@ -72,13 +52,6 @@ export function main() {
|
|||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be true when the lifecycle includes onDestroy", () => {
|
||||
expect(metadata(DirectiveNoHooks,
|
||||
new DirectiveMetadata({lifecycle: [LifecycleEvent.OnInit]}))
|
||||
.callOnInit)
|
||||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () => {
|
||||
expect(metadata(DirectiveNoHooks, new DirectiveMetadata()).callOnInit).toBe(false);
|
||||
});
|
||||
|
@ -90,13 +63,6 @@ export function main() {
|
|||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be true when the lifecycle includes doCheck", () => {
|
||||
expect(metadata(DirectiveNoHooks,
|
||||
new DirectiveMetadata({lifecycle: [LifecycleEvent.DoCheck]}))
|
||||
.callDoCheck)
|
||||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () => {
|
||||
expect(metadata(DirectiveNoHooks, new DirectiveMetadata()).callDoCheck).toBe(false);
|
||||
});
|
||||
|
@ -109,13 +75,6 @@ export function main() {
|
|||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be true when the lifecycle includes afterContentInit", () => {
|
||||
expect(metadata(DirectiveNoHooks,
|
||||
new DirectiveMetadata({lifecycle: [LifecycleEvent.AfterContentInit]}))
|
||||
.callAfterContentInit)
|
||||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () => {
|
||||
expect(metadata(DirectiveNoHooks, new DirectiveMetadata()).callAfterContentInit)
|
||||
.toBe(false);
|
||||
|
@ -129,13 +88,6 @@ export function main() {
|
|||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be true when the lifecycle includes afterContentChecked", () => {
|
||||
expect(metadata(DirectiveNoHooks,
|
||||
new DirectiveMetadata({lifecycle: [LifecycleEvent.AfterContentChecked]}))
|
||||
.callAfterContentChecked)
|
||||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () => {
|
||||
expect(metadata(DirectiveNoHooks, new DirectiveMetadata()).callAfterContentChecked)
|
||||
.toBe(false);
|
||||
|
@ -150,13 +102,6 @@ export function main() {
|
|||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be true when the lifecycle includes afterViewInit", () => {
|
||||
expect(metadata(DirectiveNoHooks,
|
||||
new DirectiveMetadata({lifecycle: [LifecycleEvent.AfterViewInit]}))
|
||||
.callAfterViewInit)
|
||||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () => {
|
||||
expect(metadata(DirectiveNoHooks, new DirectiveMetadata()).callAfterViewInit).toBe(false);
|
||||
});
|
||||
|
@ -169,13 +114,6 @@ export function main() {
|
|||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be true when the lifecycle includes afterViewChecked", () => {
|
||||
expect(metadata(DirectiveNoHooks,
|
||||
new DirectiveMetadata({lifecycle: [LifecycleEvent.AfterViewChecked]}))
|
||||
.callAfterViewChecked)
|
||||
.toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () => {
|
||||
expect(metadata(DirectiveNoHooks, new DirectiveMetadata()).callAfterViewChecked)
|
||||
.toBe(false);
|
||||
|
@ -200,7 +138,7 @@ class DirectiveWithOnCheckMethod {
|
|||
}
|
||||
|
||||
class DirectiveWithOnDestroyMethod {
|
||||
onDestroy(_) {}
|
||||
onDestroy() {}
|
||||
}
|
||||
|
||||
class DirectiveWithAfterContentInitMethod {
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
|
||||
import {Injector} from 'angular2/di';
|
||||
import {NgIf} from 'angular2/directives';
|
||||
import {Component, View, ViewMetadata, LifecycleEvent} from 'angular2/metadata';
|
||||
import {Component, View, ViewMetadata, OnDestroy} from 'angular2/metadata';
|
||||
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
|
||||
import {ElementRef} from 'angular2/src/core/compiler/element_ref';
|
||||
import {DOCUMENT} from 'angular2/src/core/render/render';
|
||||
|
@ -262,13 +262,9 @@ class ChildComp {
|
|||
|
||||
class DynamicallyCreatedComponentService {}
|
||||
|
||||
@Component({
|
||||
selector: 'hello-cmp',
|
||||
viewBindings: [DynamicallyCreatedComponentService],
|
||||
lifecycle: [LifecycleEvent.OnDestroy]
|
||||
})
|
||||
@Component({selector: 'hello-cmp', viewBindings: [DynamicallyCreatedComponentService]})
|
||||
@View({template: "{{greeting}}"})
|
||||
class DynamicallyCreatedCmp {
|
||||
class DynamicallyCreatedCmp implements OnDestroy {
|
||||
greeting: string;
|
||||
dynamicallyCreatedComponentService: DynamicallyCreatedComponentService;
|
||||
destroyed: boolean = false;
|
||||
|
|
|
@ -36,7 +36,7 @@ import {
|
|||
ViewQuery,
|
||||
ComponentMetadata,
|
||||
DirectiveMetadata,
|
||||
LifecycleEvent
|
||||
OnDestroy
|
||||
} from 'angular2/metadata';
|
||||
import {bind, Injector, Binding, Optional, Inject, Injectable, Self, SkipSelf, InjectMetadata, Host, HostMetadata, SkipSelfMetadata} from 'angular2/di';
|
||||
import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
|
||||
|
@ -217,7 +217,7 @@ class B_Needs_A {
|
|||
constructor(dep) {}
|
||||
}
|
||||
|
||||
class DirectiveWithDestroy {
|
||||
class DirectiveWithDestroy implements OnDestroy {
|
||||
onDestroyCounter: number;
|
||||
|
||||
constructor() { this.onDestroyCounter = 0; }
|
||||
|
@ -832,7 +832,7 @@ export function main() {
|
|||
it("should call onDestroy on directives subscribed to this event", () => {
|
||||
var inj = injector(ListWrapper.concat(
|
||||
[DirectiveBinding.createFromType(DirectiveWithDestroy,
|
||||
new DirectiveMetadata({lifecycle: [LifecycleEvent.OnDestroy]}))],
|
||||
new DirectiveMetadata())],
|
||||
extraBindings));
|
||||
var destroy = inj.get(DirectiveWithDestroy);
|
||||
inj.dehydrate();
|
||||
|
|
|
@ -266,8 +266,6 @@ class NoPropertyAccess {
|
|||
|
||||
@Component(
|
||||
selector: 'on-change',
|
||||
// TODO: needed because of https://github.com/angular/angular/issues/2120
|
||||
lifecycle: const [LifecycleEvent.OnChanges],
|
||||
properties: const ['prop'])
|
||||
@View(template: '')
|
||||
class OnChangeComponent implements OnChanges {
|
||||
|
@ -300,8 +298,7 @@ class ComponentWithObservableList {
|
|||
}
|
||||
|
||||
@Directive(
|
||||
selector: 'directive-logging-checks',
|
||||
lifecycle: const [LifecycleEvent.DoCheck])
|
||||
selector: 'directive-logging-checks')
|
||||
class DirectiveLoggingChecks implements DoCheck {
|
||||
Log log;
|
||||
|
||||
|
|
|
@ -13,7 +13,19 @@ import {
|
|||
TestComponentBuilder
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {Directive, Component, View, ViewMetadata, LifecycleEvent} from 'angular2/metadata';
|
||||
import {
|
||||
Directive,
|
||||
Component,
|
||||
View,
|
||||
ViewMetadata,
|
||||
OnChanges,
|
||||
OnInit,
|
||||
DoCheck,
|
||||
AfterContentInit,
|
||||
AfterContentChecked,
|
||||
AfterViewInit,
|
||||
AfterViewChecked
|
||||
} from 'angular2/metadata';
|
||||
|
||||
export function main() {
|
||||
describe('directive lifecycle integration spec', () => {
|
||||
|
@ -47,27 +59,16 @@ export function main() {
|
|||
}
|
||||
|
||||
|
||||
@Directive({selector: '[lifecycle-dir]', lifecycle: [LifecycleEvent.DoCheck]})
|
||||
class LifecycleDir {
|
||||
@Directive({selector: '[lifecycle-dir]'})
|
||||
class LifecycleDir implements DoCheck {
|
||||
constructor(private _log: Log) {}
|
||||
doCheck() { this._log.add("child_doCheck"); }
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: "[lifecycle]",
|
||||
properties: ['field'],
|
||||
lifecycle: [
|
||||
LifecycleEvent.OnChanges,
|
||||
LifecycleEvent.OnInit,
|
||||
LifecycleEvent.DoCheck,
|
||||
LifecycleEvent.AfterContentInit,
|
||||
LifecycleEvent.AfterContentChecked,
|
||||
LifecycleEvent.AfterViewInit,
|
||||
LifecycleEvent.AfterViewChecked
|
||||
]
|
||||
})
|
||||
@Component({selector: "[lifecycle]", properties: ['field']})
|
||||
@View({template: `<div lifecycle-dir></div>`, directives: [LifecycleDir]})
|
||||
class LifecycleCmp {
|
||||
class LifecycleCmp implements OnChanges, OnInit, DoCheck, AfterContentInit, AfterContentChecked,
|
||||
AfterViewInit, AfterViewChecked {
|
||||
field;
|
||||
constructor(private _log: Log) {}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Component, View, LifecycleEvent, ViewEncapsulation} from 'angular2/angular2';
|
||||
import {Component, View, LifecycleEvent, ViewEncapsulation, OnChanges} from 'angular2/angular2';
|
||||
|
||||
import {TimerWrapper} from 'angular2/src/core/facade/async';
|
||||
import {isPresent} from 'angular2/src/core/facade/lang';
|
||||
|
@ -48,7 +48,6 @@ export class MdButton {
|
|||
@Component({
|
||||
selector: 'a[md-button], a[md-raised-button], a[md-fab]',
|
||||
properties: ['disabled'],
|
||||
lifecycle: [LifecycleEvent.OnChanges],
|
||||
host: {
|
||||
'(click)': 'onClick($event)',
|
||||
'(mousedown)': 'onMousedown()',
|
||||
|
@ -63,7 +62,7 @@ export class MdButton {
|
|||
templateUrl: 'package:angular2_material/src/components/button/button.html',
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class MdAnchor extends MdButton {
|
||||
export class MdAnchor extends MdButton implements OnChanges {
|
||||
tabIndex: number;
|
||||
|
||||
/** Whether the component is disabled. */
|
||||
|
|
|
@ -4,7 +4,9 @@ import {
|
|||
ViewEncapsulation,
|
||||
Host,
|
||||
SkipSelf,
|
||||
LifecycleEvent
|
||||
OnChanges,
|
||||
OnDestroy,
|
||||
AfterContentChecked
|
||||
} from 'angular2/angular2';
|
||||
|
||||
import {ListWrapper} from 'angular2/src/core/facade/collection';
|
||||
|
@ -25,16 +27,12 @@ class RowHeightMode {
|
|||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'md-grid-list',
|
||||
properties: ['cols', 'rowHeight', 'gutterSize'],
|
||||
lifecycle: [LifecycleEvent.AfterContentChecked]
|
||||
})
|
||||
@Component({selector: 'md-grid-list', properties: ['cols', 'rowHeight', 'gutterSize']})
|
||||
@View({
|
||||
templateUrl: 'package:angular2_material/src/components/grid_list/grid_list.html',
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class MdGridList {
|
||||
export class MdGridList implements AfterContentChecked {
|
||||
/** Array of tiles that are being rendered. */
|
||||
tiles: MdGridTile[];
|
||||
|
||||
|
@ -225,14 +223,14 @@ export class MdGridList {
|
|||
'[style.left]': 'style.left',
|
||||
'[style.marginTop]': 'style.marginTop',
|
||||
'[style.paddingTop]': 'style.paddingTop',
|
||||
},
|
||||
lifecycle: [LifecycleEvent.OnDestroy, LifecycleEvent.OnChanges]
|
||||
}
|
||||
})
|
||||
@View({
|
||||
templateUrl: 'package:angular2_material/src/components/grid_list/grid_tile.html',
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class MdGridTile {
|
||||
export class MdGridTile implements OnDestroy,
|
||||
OnChanges {
|
||||
gridList: MdGridList;
|
||||
_rowspan: number;
|
||||
_colspan: number;
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
import {Directive, LifecycleEvent, Attribute, Host, SkipSelf} from 'angular2/angular2';
|
||||
import {
|
||||
Directive,
|
||||
LifecycleEvent,
|
||||
Attribute,
|
||||
Host,
|
||||
SkipSelf,
|
||||
AfterContentChecked
|
||||
} from 'angular2/angular2';
|
||||
|
||||
import {ObservableWrapper, EventEmitter} from 'angular2/src/core/facade/async';
|
||||
|
||||
|
@ -9,13 +16,12 @@ import {ObservableWrapper, EventEmitter} from 'angular2/src/core/facade/async';
|
|||
|
||||
@Directive({
|
||||
selector: 'md-input-container',
|
||||
lifecycle: [LifecycleEvent.AfterContentChecked],
|
||||
host: {
|
||||
'[class.md-input-has-value]': 'inputHasValue',
|
||||
'[class.md-input-focused]': 'inputHasFocus',
|
||||
}
|
||||
})
|
||||
export class MdInputContainer {
|
||||
export class MdInputContainer implements AfterContentChecked {
|
||||
// The MdInput or MdTextarea inside of this container.
|
||||
_input: MdInput;
|
||||
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
import {Component, LifecycleEvent, View, ViewEncapsulation, Attribute} from 'angular2/angular2';
|
||||
import {
|
||||
Component,
|
||||
LifecycleEvent,
|
||||
View,
|
||||
ViewEncapsulation,
|
||||
Attribute,
|
||||
OnChanges
|
||||
} from 'angular2/angular2';
|
||||
import {CONST} from 'angular2/src/core/facade/lang';
|
||||
import {isPresent, isBlank} from 'angular2/src/core/facade/lang';
|
||||
import {Math} from 'angular2/src/core/facade/math';
|
||||
|
||||
|
||||
/** Different display / behavior modes for progress-linear. */
|
||||
@CONST()
|
||||
class ProgressMode {
|
||||
|
@ -15,7 +21,6 @@ class ProgressMode {
|
|||
|
||||
@Component({
|
||||
selector: 'md-progress-linear',
|
||||
lifecycle: [LifecycleEvent.OnChanges],
|
||||
properties: ['value', 'bufferValue'],
|
||||
host: {
|
||||
'role': 'progressbar',
|
||||
|
@ -29,7 +34,7 @@ class ProgressMode {
|
|||
directives: [],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class MdProgressLinear {
|
||||
export class MdProgressLinear implements OnChanges {
|
||||
/** Value for the primary bar. */
|
||||
value_: number;
|
||||
|
||||
|
|
|
@ -6,7 +6,9 @@ import {
|
|||
Host,
|
||||
SkipSelf,
|
||||
Attribute,
|
||||
Optional
|
||||
Optional,
|
||||
OnChanges,
|
||||
OnInit
|
||||
} from 'angular2/angular2';
|
||||
|
||||
import {isPresent, StringWrapper, NumberWrapper} from 'angular2/src/core/facade/lang';
|
||||
|
@ -33,7 +35,6 @@ var _uniqueIdCounter: number = 0;
|
|||
|
||||
@Component({
|
||||
selector: 'md-radio-group',
|
||||
lifecycle: [LifecycleEvent.OnChanges],
|
||||
events: ['change'],
|
||||
properties: ['disabled', 'value'],
|
||||
host: {
|
||||
|
@ -49,7 +50,7 @@ var _uniqueIdCounter: number = 0;
|
|||
templateUrl: 'package:angular2_material/src/components/radio/radio_group.html',
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class MdRadioGroup {
|
||||
export class MdRadioGroup implements OnChanges {
|
||||
/** The selected value for the radio group. The value comes from the options. */
|
||||
value: any;
|
||||
|
||||
|
@ -191,7 +192,6 @@ export class MdRadioGroup {
|
|||
|
||||
@Component({
|
||||
selector: 'md-radio-button',
|
||||
lifecycle: [LifecycleEvent.OnInit],
|
||||
properties: ['id', 'name', 'value', 'checked', 'disabled'],
|
||||
host: {
|
||||
'role': 'radio',
|
||||
|
@ -207,7 +207,7 @@ export class MdRadioGroup {
|
|||
directives: [],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class MdRadioButton {
|
||||
export class MdRadioButton implements OnInit {
|
||||
/** Whether this radio is checked. */
|
||||
checked: boolean;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {verifyNoBrowserErrors} from 'angular2/src/test_lib/e2e_util';
|
||||
|
||||
describe('Template-Driven Forms', function() {
|
||||
describe('Model-Driven Forms', function() {
|
||||
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ class _DirectiveMetadataVisitor extends Object
|
|||
String _exportAs;
|
||||
bool _callOnDestroy;
|
||||
bool _callOnChange;
|
||||
bool _callOnCheck;
|
||||
bool _callDoCheck;
|
||||
bool _callOnInit;
|
||||
bool _callAfterContentInit;
|
||||
bool _callAfterContentChecked;
|
||||
|
@ -84,7 +84,7 @@ class _DirectiveMetadataVisitor extends Object
|
|||
_exportAs = null;
|
||||
_callOnDestroy = false;
|
||||
_callOnChange = false;
|
||||
_callOnCheck = false;
|
||||
_callDoCheck = false;
|
||||
_callOnInit = false;
|
||||
_callAfterContentInit = false;
|
||||
_callAfterContentChecked = false;
|
||||
|
@ -104,7 +104,7 @@ class _DirectiveMetadataVisitor extends Object
|
|||
exportAs: _exportAs,
|
||||
callOnDestroy: _callOnDestroy,
|
||||
callOnChanges: _callOnChange,
|
||||
callDoCheck: _callOnCheck,
|
||||
callDoCheck: _callDoCheck,
|
||||
callOnInit: _callOnInit,
|
||||
callAfterContentInit: _callAfterContentInit,
|
||||
callAfterContentChecked: _callAfterContentChecked,
|
||||
|
@ -170,6 +170,7 @@ class _DirectiveMetadataVisitor extends Object
|
|||
case 'host':
|
||||
_populateHost(node.expression);
|
||||
break;
|
||||
// TODO(vicb) should come from the interfaces on the class
|
||||
case 'lifecycle':
|
||||
_populateLifecycle(node.expression);
|
||||
break;
|
||||
|
@ -281,7 +282,7 @@ class _DirectiveMetadataVisitor extends Object
|
|||
var lifecycleEvents = l.elements.map((s) => s.toSource().split('.').last);
|
||||
_callOnDestroy = lifecycleEvents.contains("OnDestroy");
|
||||
_callOnChange = lifecycleEvents.contains("OnChanges");
|
||||
_callOnCheck = lifecycleEvents.contains("DoCheck");
|
||||
_callDoCheck = lifecycleEvents.contains("DoCheck");
|
||||
_callOnInit = lifecycleEvents.contains("OnInit");
|
||||
_callAfterContentInit = lifecycleEvents.contains("AfterContentInit");
|
||||
_callAfterContentChecked = lifecycleEvents.contains("AfterContentChecked");
|
||||
|
|
|
@ -21,7 +21,7 @@ const _ON_DESTROY_INTERFACES = const [
|
|||
const ClassDescriptor(
|
||||
'OnDestroy', 'package:angular2/src/core/compiler/interfaces.dart'),
|
||||
];
|
||||
const _ON_CHECK_INTERFACES = const [
|
||||
const _DO_CHECK_INTERFACES = const [
|
||||
const ClassDescriptor('DoCheck', 'package:angular2/angular2.dart'),
|
||||
const ClassDescriptor('DoCheck', 'package:angular2/metadata.dart'),
|
||||
const ClassDescriptor(
|
||||
|
@ -71,7 +71,7 @@ class InterfaceMatcher extends ClassMatcherBase {
|
|||
return new InterfaceMatcher._([]
|
||||
..addAll(_ON_CHANGE_INTERFACES)
|
||||
..addAll(_ON_DESTROY_INTERFACES)
|
||||
..addAll(_ON_CHECK_INTERFACES)
|
||||
..addAll(_DO_CHECK_INTERFACES)
|
||||
..addAll(_ON_INIT_INTERFACES)
|
||||
..addAll(_ON_AFTER_CONTENT_INIT_INTERFACES)
|
||||
..addAll(_ON_AFTER_CONTENT_CHECKED_INTERFACES)
|
||||
|
@ -88,8 +88,8 @@ class InterfaceMatcher extends ClassMatcherBase {
|
|||
implements(firstMatch(typeName, assetId), _ON_DESTROY_INTERFACES);
|
||||
|
||||
/// Checks if an [Identifier] implements [DoCheck].
|
||||
bool isOnCheck(Identifier typeName, AssetId assetId) =>
|
||||
implements(firstMatch(typeName, assetId), _ON_CHECK_INTERFACES);
|
||||
bool isDoCheck(Identifier typeName, AssetId assetId) =>
|
||||
implements(firstMatch(typeName, assetId), _DO_CHECK_INTERFACES);
|
||||
|
||||
/// Checks if an [Identifier] implements [OnInit].
|
||||
bool isOnInit(Identifier typeName, AssetId assetId) =>
|
||||
|
|
|
@ -298,8 +298,7 @@ class _NgDepsDeclarationsVisitor extends Object with SimpleAstVisitor<Object> {
|
|||
_factoryVisitor = new FactoryTransformVisitor(writer),
|
||||
_paramsVisitor = new ParameterTransformVisitor(writer),
|
||||
_metaVisitor = new AnnotationsTransformVisitor(
|
||||
writer, xhr, annotationMatcher, interfaceMatcher, assetId,
|
||||
inlineViews: inlineViews),
|
||||
writer, xhr, annotationMatcher, assetId, inlineViews: inlineViews),
|
||||
_annotationMatcher = annotationMatcher,
|
||||
_interfaceMatcher = interfaceMatcher,
|
||||
this.assetId = assetId,
|
||||
|
|
|
@ -3,11 +3,9 @@ library angular2.transform.directive_processor.visitors;
|
|||
import 'dart:async';
|
||||
import 'package:analyzer/analyzer.dart';
|
||||
import 'package:analyzer/src/generated/java_core.dart';
|
||||
import 'package:angular2/metadata.dart' show LifecycleEvent;
|
||||
import 'package:angular2/src/core/render/xhr.dart' show XHR;
|
||||
import 'package:angular2/src/transform/common/annotation_matcher.dart';
|
||||
import 'package:angular2/src/transform/common/async_string_writer.dart';
|
||||
import 'package:angular2/src/transform/common/interface_matcher.dart';
|
||||
import 'package:angular2/src/transform/common/logging.dart';
|
||||
import 'package:barback/barback.dart';
|
||||
|
||||
|
@ -214,92 +212,24 @@ class AnnotationsTransformVisitor extends ToSourceVisitor {
|
|||
final AsyncStringWriter writer;
|
||||
final XHR _xhr;
|
||||
final AnnotationMatcher _annotationMatcher;
|
||||
final InterfaceMatcher _interfaceMatcher;
|
||||
final AssetId _assetId;
|
||||
final bool _inlineViews;
|
||||
final ConstantEvaluator _evaluator = new ConstantEvaluator();
|
||||
final Set<String> _ifaceLifecycleEntries = new Set<String>();
|
||||
bool _isLifecycleWritten = false;
|
||||
bool _isProcessingView = false;
|
||||
bool _isProcessingDirective = false;
|
||||
String _ifaceLifecyclePrefix = '';
|
||||
|
||||
AnnotationsTransformVisitor(AsyncStringWriter writer, this._xhr,
|
||||
this._annotationMatcher, this._interfaceMatcher, this._assetId,
|
||||
{bool inlineViews})
|
||||
: this.writer = writer,
|
||||
this._annotationMatcher, this._assetId, {bool inlineViews})
|
||||
: writer = writer,
|
||||
_inlineViews = inlineViews,
|
||||
super(writer);
|
||||
|
||||
/// Determines if the `node` has interface-based lifecycle methods and
|
||||
/// populates `_lifecycleValue` with the appropriate values if so. If none are
|
||||
/// present, `_lifecycleValue` is not modified.
|
||||
void _populateLifecycleValue(ClassDeclaration node) {
|
||||
var populateImport = (Identifier name) {
|
||||
if (_ifaceLifecyclePrefix.isNotEmpty) return;
|
||||
var import = _interfaceMatcher.getMatchingImport(name, _assetId);
|
||||
_ifaceLifecyclePrefix =
|
||||
import != null && import.prefix != null ? '${import.prefix}.' : '';
|
||||
};
|
||||
|
||||
var namesToTest = [];
|
||||
|
||||
if (node.implementsClause != null &&
|
||||
node.implementsClause.interfaces != null &&
|
||||
node.implementsClause.interfaces.isNotEmpty) {
|
||||
namesToTest.addAll(node.implementsClause.interfaces.map((i) => i.name));
|
||||
}
|
||||
|
||||
if (node.extendsClause != null) {
|
||||
namesToTest.add(node.extendsClause.superclass.name);
|
||||
}
|
||||
|
||||
namesToTest.forEach((name) {
|
||||
if (_interfaceMatcher.isOnChange(name, _assetId)) {
|
||||
_ifaceLifecycleEntries.add('${LifecycleEvent.OnChanges}');
|
||||
populateImport(name);
|
||||
}
|
||||
if (_interfaceMatcher.isOnDestroy(name, _assetId)) {
|
||||
_ifaceLifecycleEntries.add('${LifecycleEvent.OnDestroy}');
|
||||
populateImport(name);
|
||||
}
|
||||
if (_interfaceMatcher.isOnCheck(name, _assetId)) {
|
||||
_ifaceLifecycleEntries.add('${LifecycleEvent.DoCheck}');
|
||||
populateImport(name);
|
||||
}
|
||||
if (_interfaceMatcher.isOnInit(name, _assetId)) {
|
||||
_ifaceLifecycleEntries.add('${LifecycleEvent.OnInit}');
|
||||
populateImport(name);
|
||||
}
|
||||
if (_interfaceMatcher.isAfterContentInit(name, _assetId)) {
|
||||
_ifaceLifecycleEntries.add('${LifecycleEvent.AfterContentInit}');
|
||||
populateImport(name);
|
||||
}
|
||||
if (_interfaceMatcher.isAfterContentChecked(name, _assetId)) {
|
||||
_ifaceLifecycleEntries.add('${LifecycleEvent.AfterContentChecked}');
|
||||
populateImport(name);
|
||||
}
|
||||
if (_interfaceMatcher.isAfterViewInit(name, _assetId)) {
|
||||
_ifaceLifecycleEntries.add('${LifecycleEvent.AfterViewInit}');
|
||||
populateImport(name);
|
||||
}
|
||||
if (_interfaceMatcher.isAfterViewChecked(name, _assetId)) {
|
||||
_ifaceLifecycleEntries.add('${LifecycleEvent.AfterViewChecked}');
|
||||
populateImport(name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _resetState() {
|
||||
_isLifecycleWritten = _isProcessingView = _isProcessingDirective = false;
|
||||
_ifaceLifecycleEntries.clear();
|
||||
_ifaceLifecyclePrefix = '';
|
||||
_isProcessingView = _isProcessingDirective = false;
|
||||
}
|
||||
|
||||
@override
|
||||
Object visitClassDeclaration(ClassDeclaration node) {
|
||||
_populateLifecycleValue(node);
|
||||
|
||||
writer.print('const [');
|
||||
var size = node.metadata.length;
|
||||
for (var i = 0; i < size; ++i) {
|
||||
|
@ -338,28 +268,11 @@ class AnnotationsTransformVisitor extends ToSourceVisitor {
|
|||
}
|
||||
args[i].accept(this);
|
||||
}
|
||||
if (!_isLifecycleWritten && _isProcessingDirective) {
|
||||
var lifecycleValue = _getLifecycleValue();
|
||||
if (lifecycleValue.isNotEmpty) {
|
||||
writer.print(', lifecycle: $lifecycleValue');
|
||||
_isLifecycleWritten = true;
|
||||
}
|
||||
}
|
||||
writer.print(')');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String _getLifecycleValue() {
|
||||
if (_ifaceLifecycleEntries.isNotEmpty) {
|
||||
var entries = _ifaceLifecycleEntries.toList();
|
||||
entries.sort();
|
||||
return 'const [${_ifaceLifecyclePrefix}'
|
||||
'${entries.join(", ${_ifaceLifecyclePrefix}")}]';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/// These correspond to the annotation parameters.
|
||||
@override
|
||||
Object visitNamedExpression(NamedExpression node) {
|
||||
|
@ -375,37 +288,9 @@ class AnnotationsTransformVisitor extends ToSourceVisitor {
|
|||
var isSuccess = this._inlineView(keyString, node.expression);
|
||||
if (isSuccess) return null;
|
||||
}
|
||||
if (_isProcessingDirective && keyString == 'lifecycle') {
|
||||
var isSuccess = _populateLifecycleFromNamedExpression(node.expression);
|
||||
if (isSuccess) {
|
||||
_isLifecycleWritten = true;
|
||||
writer.print('lifecycle: ${_getLifecycleValue()}');
|
||||
return null;
|
||||
} else {
|
||||
logger.warning('Failed to parse `lifecycle` value. '
|
||||
'The following `LifecycleEvent`s may not be called: '
|
||||
'(${_ifaceLifecycleEntries.join(', ')})');
|
||||
_isLifecycleWritten = true;
|
||||
// Do not return -- we will use the default processing here, maintaining
|
||||
// the original value for `lifecycle`.
|
||||
}
|
||||
}
|
||||
return super.visitNamedExpression(node);
|
||||
}
|
||||
|
||||
/// Populates the lifecycle values from explicitly declared values.
|
||||
/// Returns whether `node` was successfully processed.
|
||||
bool _populateLifecycleFromNamedExpression(AstNode node) {
|
||||
var nodeVal = node.toSource();
|
||||
for (var evt in LifecycleEvent.values) {
|
||||
var evtStr = '$evt';
|
||||
if (nodeVal.contains(evtStr)) {
|
||||
_ifaceLifecycleEntries.add(evtStr);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Inlines the template and/or style refered to by `keyString`.
|
||||
/// Returns whether the `keyString` value was successfully processed.
|
||||
bool _inlineView(String keyString, AstNode node) {
|
||||
|
|
|
@ -2,7 +2,7 @@ library examples.hello_world.index_common_dart.ng_deps.dart;
|
|||
|
||||
import 'hello.dart';
|
||||
import 'package:angular2/angular2.dart'
|
||||
show Component, Directive, View, NgElement, LifecycleEvent, ChangeDetectionStrategy;
|
||||
show Component, Directive, View, NgElement, ChangeDetectionStrategy;
|
||||
|
||||
var _visited = false;
|
||||
void initReflector(reflector) {
|
||||
|
|
|
@ -2,7 +2,7 @@ library examples.hello_world.index_common_dart.ng_deps.dart;
|
|||
|
||||
import 'hello.dart';
|
||||
import 'package:angular2/angular2.dart'
|
||||
show Component, Directive, View, NgElement, LifecycleEvent;
|
||||
show Component, Directive, View, NgElement;
|
||||
|
||||
var _visited = false;
|
||||
void initReflector(reflector) {
|
||||
|
|
|
@ -2,7 +2,7 @@ library examples.hello_world.index_common_dart.ng_deps.dart;
|
|||
|
||||
import 'hello.dart';
|
||||
import 'package:angular2/angular2.dart'
|
||||
show Component, Directive, View, NgElement, LifecycleEvent;
|
||||
show Component, Directive, View, NgElement;
|
||||
|
||||
var _visited = false;
|
||||
void initReflector(reflector) {
|
||||
|
|
|
@ -104,10 +104,6 @@ void allTests() {
|
|||
_testProcessor('should not include superclasses in `interfaces`.',
|
||||
'superclass_files/soup.dart');
|
||||
|
||||
_testProcessor(
|
||||
'should populate `lifecycle` when lifecycle interfaces are present.',
|
||||
'interface_lifecycle_files/soup.dart');
|
||||
|
||||
_testProcessor('should populate multiple `lifecycle` values when necessary.',
|
||||
'multiple_interface_lifecycle_files/soup.dart');
|
||||
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
library dinner.soup.ng_deps.dart;
|
||||
|
||||
import 'soup.dart';
|
||||
export 'soup.dart';
|
||||
import 'package:angular2/src/core/reflection/reflection.dart' as _ngRef;
|
||||
import 'package:angular2/metadata.dart';
|
||||
|
||||
var _visited = false;
|
||||
void initReflector() {
|
||||
if (_visited) return;
|
||||
_visited = true;
|
||||
_ngRef.reflector
|
||||
..registerType(
|
||||
OnChangeSoupComponent,
|
||||
new _ngRef.ReflectionInfo(
|
||||
const [
|
||||
const Component(
|
||||
selector: '[soup]',
|
||||
lifecycle: const [LifecycleEvent.OnChanges])
|
||||
],
|
||||
const [],
|
||||
() => new OnChangeSoupComponent(),
|
||||
const [OnChanges]))
|
||||
..registerType(
|
||||
OnDestroySoupComponent,
|
||||
new _ngRef.ReflectionInfo(
|
||||
const [
|
||||
const Component(
|
||||
selector: '[soup]',
|
||||
lifecycle: const [LifecycleEvent.OnDestroy])
|
||||
],
|
||||
const [],
|
||||
() => new OnDestroySoupComponent(),
|
||||
const [OnDestroy]))
|
||||
..registerType(
|
||||
OnCheckSoupComponent,
|
||||
new _ngRef.ReflectionInfo(
|
||||
const [
|
||||
const Component(
|
||||
selector: '[soup]', lifecycle: const [LifecycleEvent.DoCheck])
|
||||
],
|
||||
const [],
|
||||
() => new OnCheckSoupComponent(),
|
||||
const [DoCheck]))
|
||||
..registerType(
|
||||
OnInitSoupComponent,
|
||||
new _ngRef.ReflectionInfo(
|
||||
const [
|
||||
const Component(
|
||||
selector: '[soup]', lifecycle: const [LifecycleEvent.OnInit])
|
||||
],
|
||||
const [],
|
||||
() => new OnInitSoupComponent(),
|
||||
const [OnInit]))
|
||||
..registerType(
|
||||
AfterContentInitSoupComponent,
|
||||
new _ngRef.ReflectionInfo(
|
||||
const [
|
||||
const Component(
|
||||
selector: '[soup]',
|
||||
lifecycle: const [LifecycleEvent.AfterContentInit])
|
||||
],
|
||||
const [],
|
||||
() => new AfterContentInitSoupComponent(),
|
||||
const [AfterContentInit]))
|
||||
..registerType(
|
||||
AfterContentCheckedSoupComponent,
|
||||
new _ngRef.ReflectionInfo(
|
||||
const [
|
||||
const Component(
|
||||
selector: '[soup]',
|
||||
lifecycle: const [LifecycleEvent.AfterContentChecked])
|
||||
],
|
||||
const [],
|
||||
() => new AfterContentCheckedSoupComponent(),
|
||||
const [AfterContentChecked]))
|
||||
..registerType(
|
||||
AfterViewInitSoupComponent,
|
||||
new _ngRef.ReflectionInfo(
|
||||
const [
|
||||
const Component(
|
||||
selector: '[soup]',
|
||||
lifecycle: const [LifecycleEvent.AfterViewInit])
|
||||
],
|
||||
const [],
|
||||
() => new AfterViewInitSoupComponent(),
|
||||
const [AfterViewInit]))
|
||||
..registerType(
|
||||
AfterViewCheckedSoupComponent,
|
||||
new _ngRef.ReflectionInfo(
|
||||
const [
|
||||
const Component(
|
||||
selector: '[soup]',
|
||||
lifecycle: const [LifecycleEvent.AfterViewChecked])
|
||||
],
|
||||
const [],
|
||||
() => new AfterViewCheckedSoupComponent(),
|
||||
const [AfterViewChecked]));
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
library dinner.soup;
|
||||
|
||||
import 'package:angular2/metadata.dart';
|
||||
|
||||
@Component(selector: '[soup]')
|
||||
class OnChangeSoupComponent implements OnChanges {}
|
||||
|
||||
@Component(selector: '[soup]')
|
||||
class OnDestroySoupComponent implements OnDestroy {}
|
||||
|
||||
@Component(selector: '[soup]')
|
||||
class OnCheckSoupComponent implements DoCheck {}
|
||||
|
||||
@Component(selector: '[soup]')
|
||||
class OnInitSoupComponent implements OnInit {}
|
||||
|
||||
@Component(selector: '[soup]')
|
||||
class AfterContentInitSoupComponent implements AfterContentInit {}
|
||||
|
||||
@Component(selector: '[soup]')
|
||||
class AfterContentCheckedSoupComponent implements AfterContentChecked {}
|
||||
|
||||
@Component(selector: '[soup]')
|
||||
class AfterViewInitSoupComponent implements AfterViewInit {}
|
||||
|
||||
@Component(selector: '[soup]')
|
||||
class AfterViewCheckedSoupComponent implements AfterViewChecked {}
|
|
@ -14,40 +14,9 @@ void initReflector() {
|
|||
MultiSoupComponent,
|
||||
new _ngRef.ReflectionInfo(
|
||||
const [
|
||||
const Component(
|
||||
selector: '[soup]',
|
||||
lifecycle: const [
|
||||
LifecycleEvent.OnChanges,
|
||||
LifecycleEvent.OnDestroy,
|
||||
LifecycleEvent.OnInit
|
||||
])
|
||||
const Component(selector: '[soup]')
|
||||
],
|
||||
const [],
|
||||
() => new MultiSoupComponent(),
|
||||
const [OnChanges, OnDestroy, OnInit]))
|
||||
..registerType(
|
||||
MixedSoupComponent,
|
||||
new _ngRef.ReflectionInfo(
|
||||
const [
|
||||
const Component(
|
||||
selector: '[soup]',
|
||||
lifecycle: const [
|
||||
LifecycleEvent.DoCheck,
|
||||
LifecycleEvent.OnChanges
|
||||
])
|
||||
],
|
||||
const [],
|
||||
() => new MixedSoupComponent(),
|
||||
const [OnChanges]))
|
||||
..registerType(
|
||||
MatchedSoupComponent,
|
||||
new _ngRef.ReflectionInfo(
|
||||
const [
|
||||
const Component(
|
||||
selector: '[soup]',
|
||||
lifecycle: const [LifecycleEvent.OnChanges])
|
||||
],
|
||||
const [],
|
||||
() => new MatchedSoupComponent(),
|
||||
const [OnChanges]));
|
||||
const [OnChanges, OnDestroy, OnInit]));
|
||||
}
|
||||
|
|
|
@ -4,9 +4,3 @@ import 'package:angular2/metadata.dart';
|
|||
|
||||
@Component(selector: '[soup]')
|
||||
class MultiSoupComponent implements OnChanges, OnDestroy, OnInit {}
|
||||
|
||||
@Component(selector: '[soup]', lifecycle: const [LifecycleEvent.DoCheck])
|
||||
class MixedSoupComponent implements OnChanges {}
|
||||
|
||||
@Component(selector: '[soup]', lifecycle: const [LifecycleEvent.OnChanges])
|
||||
class MatchedSoupComponent implements OnChanges {}
|
||||
|
|
|
@ -15,8 +15,7 @@ void initReflector() {
|
|||
new _ngRef.ReflectionInfo(
|
||||
const [
|
||||
const prefix.Component(
|
||||
selector: '[soup]',
|
||||
lifecycle: const [prefix.LifecycleEvent.OnChanges])
|
||||
selector: '[soup]')
|
||||
],
|
||||
const [],
|
||||
() => new OnChangeSoupComponent(),
|
||||
|
|
|
@ -14,6 +14,6 @@ void initReflector() {
|
|||
OnChangeSoupComponent,
|
||||
new _ngRef.ReflectionInfo(const [
|
||||
const Component(
|
||||
selector: '[soup]', lifecycle: const [LifecycleEvent.OnChanges])
|
||||
selector: '[soup]')
|
||||
], const [], () => new OnChangeSoupComponent()));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue