Skip to content
This repository was archived by the owner on Sep 16, 2022. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
286 changes: 54 additions & 232 deletions lib/src/core/metadata/lifecycle_hooks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -77,75 +77,33 @@ abstract class OnInit {
/// Implement this interface to override the default change detection algorithm
/// for your directive.
///
/// `ngDoCheck` gets called to check the changes in the directives instead of
/// [ngDoCheck] gets called to check the changes in the directives instead of
/// the default algorithm.
///
/// The default change detection algorithm looks for differences by comparing
/// bound-property values by reference across change detection runs. When
/// `DoCheck` is implemented, the default algorithm is disabled and `ngDoCheck`
/// [DoCheck] is implemented, the default algorithm is disabled and [ngDoCheck]
/// is responsible for checking for changes.
///
/// Implementing this interface allows improving performance by using insights
/// about the component, its implementation and data types of its properties.
///
/// Note that a directive should not implement both `DoCheck` and [OnChanges] at
/// the same time. `ngOnChanges` would not be called when a directive
/// implements `DoCheck`. Reaction to the changes have to be handled from within
/// the `ngDoCheck` callback.
/// Note that a directive should not implement both [DoCheck] and [OnChanges] at
/// the same time. [ngOnChanges] would not be called when a directive
/// implements [DoCheck]. Reaction to the changes have to be handled from within
/// the [ngDoCheck] callback.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you verify this. I vaguely remember discussions in TS that this is not actually the case.
Seems I even started it myself :D angular/angular#6810

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the cross link to 6810. No I did not double check, but the statements did seem a little strange to me.

I'll let @matanlurey @ferhatb or @thso reply as to the accuracy of the statements.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

///
/// Use [KeyValueDiffers] and [IterableDiffers] to add your custom check
/// mechanisms.
///
/// ### Example
///
/// In the following example `ngDoCheck` uses an [IterableDiffers] to detect the
/// updates to the array `list`:
///
/// ```dart
/// @Component(
/// selector: 'custom-check',
/// template: '''
/// <p>Changes:</p>
/// <ul>
/// <li *ngFor="let line of logs">{{line}}</li>
/// </ul>
/// ''',
/// directives: const [NgFor]
/// )
/// class CustomCheckComponent implements DoCheck {
/// final IterableDiffer differ;
/// final List<String> logs = [];
///
/// @Input()
/// List list;
///
/// CustomCheckComponent(IterableDiffers differs) :
/// differ = differs.find([]).create(null);
///
/// @override
/// ngDoCheck() {
/// var changes = differ.diff(list);
///
/// if (changes is DefaultIterableDiffer) {
/// changes.forEachAddedItem(r => logs.add('added ${r.item}'));
/// changes.forEachRemovedItem(r => logs.add('removed ${r.item}'))
/// }
/// }
/// }
///
/// @Component({
/// selector: 'app',
/// template: '''
/// <button (click)="list.push(list.length)">Push</button>
/// <button (click)="list.pop()">Pop</button>
/// <custom-check [list]="list"></custom-check>
/// ''',
/// directives: const [CustomCheckComponent]
/// })
/// class App {
/// List list = [];
/// }
/// ```
/// ### Examples
///
/// Try this [live example][ex] from the [Lifecycle Hooks][docs] page:
///
/// {@example docs/lifecycle-hooks/lib/do_check_component.dart region=ng-do-check}
///
/// [docs]: docs/guide/lifecycle-hooks.html#docheck
/// [ex]: examples/lifecycle-hooks#docheck
abstract class DoCheck {
ngDoCheck();
}
Expand All @@ -170,203 +128,67 @@ abstract class OnDestroy {
/// Implement this interface to get notified when your directive's content has
/// been fully initialized.
///
/// ### Example
///
/// ```dart
/// @Component(
/// selector: 'child-cmp',
/// template: '{{where}} child'
/// )
/// class ChildComponent {
/// @Input()
/// String where;
/// }
///
/// @Component(
/// selector: 'parent-cmp',
/// template: '<ng-content></ng-content>'
/// )
/// class ParentComponent implements AfterContentInit {
/// @ContentChild(ChildComponent)
/// ChildComponent contentChild;;
///
/// ParentComponent() {
/// // contentChild is not initialized yet
/// print(_message(contentChild));
/// }
///
/// @override
/// ngAfterContentInit() {
/// // contentChild is updated after the content has been checked
/// print('AfterContentInit: ' + _message(contentChild));
/// }
///
/// String _message(ChildComponent cmp) =>
/// cmp == null ? 'no child' : '${cmp.where} child';
/// }
///
/// @Component(
/// selector: 'app',
/// template: '''
/// <parent-cmp>
/// <child-cmp where="content"></child-cmp>
/// </parent-cmp>
/// ''',
/// directives: const [ParentComponent, ChildComponent]
/// )
/// class App {}
/// ```
/// ### Examples
///
/// Try this [live example][ex] from the [Lifecycle Hooks][docs] page:
///
/// {@example docs/lifecycle-hooks/lib/after_content_component.dart region=template}
///
/// {@example docs/lifecycle-hooks/lib/after_content_component.dart region=hooks}
///
/// [docs]: docs/guide/lifecycle-hooks.html#aftercontent
/// [ex]: examples/lifecycle-hooks#after-content
abstract class AfterContentInit {
ngAfterContentInit();
}

/// Implement this interface to get notified after every check of your
/// directive's content.
///
/// ### Example
///
/// ```dart
/// @Component(selector: 'child-cmp', template: '{{where}} child')
/// class ChildComponent {
/// @Input()
/// String where;
/// }
///
/// @Component(selector: 'parent-cmp', template: '<ng-content></ng-content>')
/// class ParentComponent implements AfterContentChecked {
/// @ContentChild(ChildComponent)
/// ChildComponent contentChild;
///
/// ParentComponent() {
/// // contentChild is not initialized yet
/// print(_message(contentChild));
/// }
///
/// @override
/// ngAfterContentChecked() {
/// // contentChild is updated after the content has been checked
/// print('AfterContentChecked: ${_message(contentChild)}');
/// }
///
/// String _message(ChildComponent cmp) =>
/// cmp == null ? 'no child' : '${cmp.where} child';
/// }
///
/// @Component(
/// selector: 'app',
/// template: '''
/// <parent-cmp>
/// <button (click)="hasContent = !hasContent">
/// Toggle content child
/// </button>
/// <child-cmp *ngIf="hasContent" where="content"></child-cmp>
/// </parent-cmp>
/// ''',
/// directives: const [NgIf, ParentComponent, ChildComponent]
/// )
/// class App {
/// bool hasContent = true;
/// }
/// ```
/// ### Examples
///
/// Try this [live example][ex] from the [Lifecycle Hooks][docs] page:
///
/// {@example docs/lifecycle-hooks/lib/after_content_component.dart region=template}
///
/// {@example docs/lifecycle-hooks/lib/after_content_component.dart region=hooks}
///
/// [docs]: docs/guide/lifecycle-hooks.html#aftercontent
/// [ex]: examples/lifecycle-hooks#after-content
abstract class AfterContentChecked {
ngAfterContentChecked();
}

/// Implement this interface to get notified when your component's view has been
/// fully initialized.
///
/// ### Example
///
/// ```dart
/// @Component(selector: 'child-cmp', template: '{{where}} child')
/// class ChildComponent {
/// @Input()
/// String where;
/// }
///
/// @Component(
/// selector: 'parent-cmp',
/// template: '<child-cmp where="view"></child-cmp>',
/// directives: const [ChildComponent]
/// )
/// class ParentComponent implements AfterViewInit {
/// @ViewChild(ChildComponent)
/// ChildComponent viewChild;
///
/// ParentComponent() {
/// // viewChild is not initialized yet
/// print(_message(viewChild));
/// }
///
/// @override
/// ngAfterViewInit() {
/// // viewChild is updated after the view has been initialized
/// print('ngAfterViewInit: ' + _message(viewChild));
/// }
///
/// String _message(ChildComponent cmp) =>
/// cmp == null ? 'no child' : '${cmp.where} child';
/// }
///
/// @Component(
/// selector: 'app',
/// template: '<parent-cmp></parent-cmp>',
/// directives: const [ParentComponent]
/// )
/// class App {}
/// ```
/// ### Examples
///
/// Try this [live example][ex] from the [Lifecycle Hooks][docs] page:
///
/// {@example docs/lifecycle-hooks/lib/after_view_component.dart region=template}
///
/// {@example docs/lifecycle-hooks/lib/after_view_component.dart region=hooks}
///
/// [docs]: docs/guide/lifecycle-hooks.html#afterview
/// [ex]: examples/lifecycle-hooks#after-view
abstract class AfterViewInit {
ngAfterViewInit();
}

/// Implement this interface to get notified after every check of your
/// component's view.
///
/// ### Example
///
/// ```dart
/// @Component(selector: 'child-cmp', template: '{{where}} child')
/// class ChildComponent {
/// @Input()
/// String where;
/// }
///
/// @Component(
/// selector: 'parent-cmp',
/// template: '''
/// <button (click)="showView = !showView">Toggle view child</button>
/// <child-cmp *ngIf="showView" where="view"></child-cmp>
/// ''',
/// directives: const [NgIf, ChildComponent]
/// )
/// class ParentComponent implements AfterViewChecked {
/// @ViewChild(ChildComponent)
/// ChildComponent viewChild;
///
/// bool showView = true;
///
/// ParentComponent() {
/// // viewChild is not initialized yet
/// print(_message(viewChild));
/// }
///
/// @override
/// ngAfterViewChecked() {
/// // viewChild is updated after the view has been checked
/// print('AfterViewChecked: ${_message(viewChild)}');
/// }
///
/// String _message(ChildComponent cmp) =>
/// cmp == null ? 'no child' : '${cmp.where} child';
/// }
///
/// @Component(
/// selector: 'app',
/// template: '<parent-cmp></parent-cmp>',
/// directives: const [ParentComponent]
/// )
/// class App {}
/// ```
/// ### Examples
///
/// Try this [live example][ex] from the [Lifecycle Hooks][docs] page:
///
/// {@example docs/lifecycle-hooks/lib/after_view_component.dart region=template}
///
/// {@example docs/lifecycle-hooks/lib/after_view_component.dart region=hooks}
///
/// [docs]: docs/guide/lifecycle-hooks.html#afterview
/// [ex]: examples/lifecycle-hooks#after-view
abstract class AfterViewChecked {
ngAfterViewChecked();
}
14 changes: 4 additions & 10 deletions lib/src/router/directives/router_link.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,12 @@ import "../router.dart" show Router;
/// The RouterLink directive lets you link to specific parts of your app.
///
/// Consider the following route configuration:
/// ```
/// @RouteConfig([
/// { path: '/user', component: UserCmp, as: 'User' }
/// ]);
/// class MyComp {}
/// ```
///
/// When linking to this `User` route, you can write:
/// {@example docs/toh-5/lib/app_component.dart region=heroes}
///
/// ```
/// <a [routerLink]="['./User']">link to user component</a>
/// ```
/// When linking to this `Heroes` route, you can write:
///
/// {@example docs/toh-5/lib/app_component_1.dart region=template-v2}
///
/// RouterLink expects the value to be an array of route names, followed by the params
/// for that level of routing. For instance `['/Team', {teamId: 1}, 'User', {userId: 2}]`
Expand Down
10 changes: 6 additions & 4 deletions lib/src/router/directives/router_outlet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ var _resolveToTrue = new Future.value(true);

/// A router outlet is a placeholder that Angular dynamically fills based on the application's route.
///
/// ## Use
/// ### Example
///
/// ```
/// <router-outlet></router-outlet>
/// ```
/// Here is an example from the [tutorial on routing][routing]:
///
/// {@example docs/toh-5/lib/app_component.dart region=template}
///
/// [routing]: docs/tutorial/toh-pt5.html#router-outlet
@Directive(selector: "router-outlet")
class RouterOutlet implements OnDestroy {
ViewContainerRef _viewContainerRef;
Expand Down
10 changes: 8 additions & 2 deletions lib/src/router/route_config/route_config_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@ export "../route_definition.dart" show RouteDefinition;

Future<dynamic> ___make_dart_analyzer_happy;

/// The `RouteConfig` decorator defines routes for a given component.
/// The [RouteConfig] decorator defines routes for a given component.
///
/// It takes an array of [RouteDefinition]s.
/// ### Example
///
/// Here is an example from the [tutorial on routing][routing]:
///
/// {@example docs/toh-5/lib/app_component.dart region=routes}
///
/// [routing]: docs/tutorial/toh-pt5.html#configure-routes
class RouteConfig {
final List<RouteDefinition> configs;
const RouteConfig(this.configs);
Expand Down