Skip to content
This repository has been archived by the owner on Feb 22, 2018. It is now read-only.

Commit

Permalink
docs: add more scope and change detection docs for 0.9.11
Browse files Browse the repository at this point in the history
  • Loading branch information
naomiblack committed Apr 17, 2014
1 parent 30e9f0b commit 8c05db6
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 23 deletions.
10 changes: 10 additions & 0 deletions lib/application.dart
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ abstract class Application {
final List<Module> modules = <Module>[];
dom.Element element;

/**
* Creates a selector for a DOM element.
*/
dom.Element selector(String selector) => element = _find(selector);

Application(): element = _find('[ng-app]', dom.window.document.documentElement) {
Expand All @@ -148,6 +151,9 @@ abstract class Application {
..factory(dom.Node, (i) => i.get(Application).element);
}

/**
* Returns the injector for this module.
*/
Injector injector;

Application addModule(Module module) {
Expand All @@ -174,5 +180,9 @@ abstract class Application {
});
}

/**
* Creates an injector function that can be used for retrieving services as well as for
* dependency injection.
*/
Injector createInjector();
}
14 changes: 13 additions & 1 deletion lib/application_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,17 @@ class _DynamicApplication extends Application {

Injector createInjector() => new DynamicInjector(modules: modules);
}

/**
* Creates an `applicationFactory` that bootstraps Angular as part of the `main()` function.
*
* main() {
* applicationFactory()
* .addModule(new MyModule())
* .run();
* }
*
* During `pub build`, `applicationFactory()` is replaced by `staticApplication()` and
* populated with the getters, setters, annotations, and factories generated by
* Angular's transformers for dart2js compilation.
*/
Application applicationFactory() => new _DynamicApplication();
29 changes: 28 additions & 1 deletion lib/application_factory_static.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,34 @@ class _StaticApplication extends Application {
Injector createInjector() =>
new StaticInjector(modules: modules, typeFactories: typeFactories);
}

/**
*
* Bootstraps Angular as part of the `main()` function.
*
* `staticApplication()` replaces `dynamicApplication()` in the main function during pub build,
* and is populated with the getters, setters, annotations, and factories generated by
* Angular's transformers for dart2js compilation. It is not typically called directly.
*
* For example,
*
* main() {
* applicationFactory()
* .addModule(new Module()..type(HelloWorld))
* .run();
* }
*
* becomes:
*
* main() {
* staticApplication(generated_static_injector.factories,
* generated_static_metadata.typeAnnotations,
* generated_static_expressions.getters,
* generated_static_expressions.setters,
* generated_static_expressions.symbols)
* .addModule(new Module()..type(HelloWorldController))
* .run();
*
*/
Application staticApplicationFactory(
Map<Type, TypeFactory> typeFactories,
Map<Type, Object> metadata,
Expand Down
12 changes: 12 additions & 0 deletions lib/change_detection/watch_group.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ part 'linked_list.dart';
part 'ast.dart';
part 'prototype_map.dart';

/**
* A function that is notified of changes to the model.
*
* ReactionFn is a function implemented by the developer that executes when a change is detected
* in a watched expression.
*
* * [value]: The current value of the watched expression.
* * [previousValue]: The previous value of the watched expression.
*
* If the expression is watching a collection (a list or a map), then [value] is wrapped in
* a [CollectionChangeItem] that lists all the changes.
*/
typedef void ReactionFn(value, previousValue);
typedef void ChangeLog(String expression, current, previous);

Expand Down
2 changes: 2 additions & 0 deletions lib/core/module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
*/
library angular.core;

export "package:angular/change_detection/watch_group.dart" show
ReactionFn;

export "package:angular/core/parser/parser.dart" show
Parser;
Expand Down
73 changes: 52 additions & 21 deletions lib/core/scope.dart
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,22 @@ class Scope {
this._stats);

/**
* Use [watch] to set up a watch in the [apply] cycle.
* Use [watch] to set up change detection on an expression.
*
* When [canChangeModel] is [:false:], the watch will be executed in the
* [flush] cycle. It should be used when the [reactionFn] does not change the
* model and allows speeding up the [digest] phase.
*
* On the opposite, [canChangeModel] should be set to [:true:] if the
* [reactionFn] could change the model so that the watch is evaluated in the
* [digest] cycle.
* * [expression]: The expression to watch for changes.
* * [reactionFn]: The reaction function to execute when a change is detected in the watched
* expression.
* * [context]: The object against which the expression is evaluated. This defaults to the
* [Scope.context] if no context is specified.
* * [formatters]: If the watched expression contains formatters,
* this map specifies the set of formatters that are used by the expression.
* * [canChangeModel]: Specifies whether the [reactionFn] changes the model. Reaction
* functions that change the model are processed as part of the [digest] cycle. Otherwise,
* they are processed as part of the [flush] cycle.
* * [collection]: If [:true:], then the expression points to a collection (a list or a map),
* and the collection should be shallow watched. If [:false:] then the expression is watched
* by reference. When watching a collection, the reaction function receives a
* [CollectionChangeItem] that lists all the changes.
*/
Watch watch(String expression, ReactionFn reactionFn, {context,
FormatterMap formatters, bool canChangeModel: true, bool collection: false}) {
Expand Down Expand Up @@ -538,18 +545,24 @@ class RootScope extends Scope {
* While processing data bindings, Angular passes through multiple states. When testing or
* debugging, it can be useful to access the current `state`, which is one of the following:
*
* ## `null`
* * null
* * apply
* * digest
* * flush
* * assert
*
* ##null
*
* Angular is not currently processing changes
*
* ## `apply`
* ##apply
*
* The apply state begins by executing the optional expression within the context of
* The apply state begins by executing the optional expression within the context of
* angular change detection mechanism. Any exceptions are delegated to [ExceptionHandler]. At the
* end of apply state RootScope enters the digest followed by flush phase (optionally if asserts
* enabled run assert phase.).
* enabled run assert phase.)
*
* ## `digest`
* ##digest
*
* The apply state begins by processing the async queue,
* followed by change detection
Expand All @@ -558,18 +571,19 @@ class RootScope extends Scope {
* iterations the model is considered unstable and angular exists with an exception. (See
* ScopeDigestTTL)
*
* ## `flush`
* ##flush
*
* Flush phase consist of these steps.
* 1) processing the DOM write queue,
* 2) followed by change detection on DOM only updates (these are reaction functions which must
* The flush phase consists of these steps:
*
* 1. processing the DOM write queue
* 2. change detection on DOM only updates (these are reaction functions which must
* not change the model state and hence don't need stabilization as in digest phase).
* 3) processing the DOM read queue
* 4) repeat step 1/3 (not 2) until queues are empty
* 3. processing the DOM read queue
* 4. repeat steps 1 and 3 (not 2) until queues are empty
*
* ## `assert`
* ##assert
*
* Optionally if dart assert is on, verify that flush reaction functions did not make any changes
* Optionally if Dart assert is on, verify that flush reaction functions did not make any changes
* to model and throw error if changes detected.
*
*/
Expand All @@ -596,6 +610,23 @@ class RootScope extends Scope {
RootScope get rootScope => this;
bool get isAttached => true;

/**
* Propagates changes between different parts of the application model. Normally called by
* [VMTurnZone] right before DOM rendering to initiate data binding. May also be called directly
* for unit testing.
*
* Before each iteration of change detection, [digest] first processes the async queue. Any
* work scheduled on the queue is executed before change detection. Since work scheduled on
* the queue may generate more async calls, [digest] must process the queue multiple times before
* it completes. The async queue must be empty before the model is considered stable.
*
* Next, [digest] collects the changes that have occurred in the model. For each change,
* [digest] calls the associated [ReactionFn]. Since a [ReactionFn] may further change the model,
* [digest] processes changes multiple times until no more changes are detected.
*
* If the model does not stabilize within 5 iterations, an exception is thrown. See
* [ScopeDigestTTL].
*/
void digest() {
_transitionState(null, STATE_DIGEST);
try {
Expand Down

0 comments on commit 8c05db6

Please sign in to comment.