diff --git a/modules/angular2/docs/change_detection/change_detection.md b/modules/angular2/docs/change_detection/change_detection.md index 4a6f8dd63f92..c34d7550b321 100644 --- a/modules/angular2/docs/change_detection/change_detection.md +++ b/modules/angular2/docs/change_detection/change_detection.md @@ -1,5 +1,16 @@ # Change Detection +Change Detection is a mechanism of detecting changes in the model so that they can be propageted to the destination. Changes are detected and propageted in a top down manner from the root View to the child Views in a depth first traversal. + + +## `ChangeDetector`s + +Each View has an associated `ChangeDetector` class with it. (Some Views may have more than one `ChangeDetector` to support partial views updates as is the case with `[hidden]` bindings.) `ChangeDetector`s are arranged in + + + + + * Mechanisms by which changes are detected in the model * DAG * Order of evaluation diff --git a/modules/angular2/docs/change_detection/expressions.md b/modules/angular2/docs/change_detection/expressions.md index e9cdc9aa9bb6..d2a513f36388 100644 --- a/modules/angular2/docs/change_detection/expressions.md +++ b/modules/angular2/docs/change_detection/expressions.md @@ -1,7 +1,167 @@ -# Expressions +# Expressions and Statements + +Expressions and statements are small code snippets which are placed in the Angular templates. Following example shows where in the template can expressions and statements be located. + +``` +

{{expression}}

+
+ +
...
+``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExpressionsStatements
Used in:String in; Property binding; Template bindingEvents
ExecutionDuring Change DetectionDue to event before Change Detection
Null dereferenceForgiving / SilentError
Idempotent (side-effects)NOYES
AssignmentsNot allowedAllowed
MultipleSingle expressionMultiple statements separated by ';'
FormattersAllowed at an end of expression onlyNot allowed
+ + + +## Expressions + +Expressions are bindings which are executed as part of the Change Detection. While Change Detection guarantees that the changes are delived in the order in which they are declared in the template, the individual sub-parts of the expressions may be executed in any order due to sub-expression coelescence. + +Example `Hello: {{user.last}}, {{user.first}}` is made up of `user`, `last`, and `first`. The change detection may chose to evaluate the `user` only once since it is a common sub-expression for the two expressions used in the binding. + +Expressions are forgiving in nature. In the above example if `user` is `null` the `user.last` will not throw an error, instead it will result in an `null` which will consequently be rendered as an empty string. This is done because during the data loading it is very common for sub-expressions to not be defined yet and placing guards around each expressions would result in too much boilerplate. + + +### Expressions Semantics + +The expressions follow the semantics of the underlying platform with the exception of silent null dereferencing. This means that they follow JavaScript semantis in AngularJS, and Dart semantics in AngularDart. + +Some example of different semantics between JavaScript and Dart: + +- `'one' + 2`: will result in `one2` in JavaScript, but an error in Dart. +- `obj['prop']`: will work for all objects in JavaScript, but only for `Map`s in Dart. (NOTE: ES6 `Map` require `obj.get('prop')`) + + +### Expression Syntax + +Expression syntax follows that of the platform, with few limitations (no assignment and no keywords: `if`, `for`, etc) and additon of Formatters. + +Here is the list of allowed operations in Angular Expressions. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameSyntaxNotes
Dereference`obj.prop`Silently ignores if `obj` is `null` or `undefined`.
Map`obj[key]`Silently ignores if `obj` is `null` or `undefined`.
JavaScript treats `obj.prop` and `obj['prop']` same, but Dart only allows `obj['prop']` on Maps.
Operators:`+`, `-`, `/`, `*`,
`<`, `<=`, `<>`, `>=`,
`==`, `!=`
`!`
JavaScript does type coercion, Dart requires types to match.
Invocation`fn(args)`
Formattersexpr | formatter:arg0:...Formatters must be at the end of the expression. The formatter arguments are separated by `:`, which in turn can be expressions.
TruthynessIn Dart only values which are `Boolean` and `true` are consider truthy. In JavaScript type coercion allows many other things to be consider true.
+ -## Binding Semantics ### Formatters -## Statement Semantics \ No newline at end of file +Formatters are pure functions which can transform the input model to a different more usable data format. Examples include converting `Date` type to localized string or limiting the items in an array for filtering of `Foreach` items in a repeater. + +Formatters can only be placed at the end of an `expression` (i.e. they can not be part of sub-expressions.) Formatters can be chained together, where the output of one formatter becomes an input of the next. + +Formatters can take arguments, which are themselves an `expression`s separetd by `:`. + +Here are some examples: + +- `date | localizedDate` - Example of a formatter. +- `date | localizedDate:'short'` - Example of a formatter takeing an argument. +- `map | toArray | filter:predicate` - Example of formatter chaining. + + +## Statement Semantics + +Statements execute in response to an event. Syntactically statements are identical to expressions with few differences: + +1. assignments are allowed +2. `null` dereference is an error +3. multiple statements separated by `;` +4. Formatters are not allowed. + + + + + + + + + + + + + + + + + + + + + + +
NameSyntaxNotes
Dereference`obj.prop`, `obj[key]`Throws if `obj` is `null` or `undefined`.
Assignment`=`Allowed in statements only.
FormattersNot allowed in statements.
diff --git a/modules/angular2/docs/change_detection/record.md b/modules/angular2/docs/change_detection/record.md deleted file mode 100644 index 343624acec22..000000000000 --- a/modules/angular2/docs/change_detection/record.md +++ /dev/null @@ -1,3 +0,0 @@ -# Record - -## RecordRange \ No newline at end of file diff --git a/modules/angular2/docs/core/01_templates.md b/modules/angular2/docs/core/01_templates.md index a85506bb9a91..2cfebbee139c 100644 --- a/modules/angular2/docs/core/01_templates.md +++ b/modules/angular2/docs/core/01_templates.md @@ -417,6 +417,15 @@ microsyntax for `foreach`. ``` +Finally, we can pull the `foreach` selector into the attribute key and prefix it with `!`. + +``` + +``` + + The format is intentionally defined freely, so that developers of directives can build expressive microsyntax for their directives. Following describes a more formal definition. diff --git a/modules/angular2/docs/core/04_decorator_directive.md b/modules/angular2/docs/core/04_decorator_directive.md index e69de29bb2d1..8b0a1b442533 100644 --- a/modules/angular2/docs/core/04_decorator_directive.md +++ b/modules/angular2/docs/core/04_decorator_directive.md @@ -0,0 +1,2 @@ +# Decorators + diff --git a/modules/angular2/docs/core/06_instantiator_directive.md b/modules/angular2/docs/core/06_instantiator_directive.md index e69de29bb2d1..f0bf7719f8fa 100644 --- a/modules/angular2/docs/core/06_instantiator_directive.md +++ b/modules/angular2/docs/core/06_instantiator_directive.md @@ -0,0 +1,2 @@ +# Instantiators + diff --git a/modules/angular2/docs/core/08_lifecycle.md b/modules/angular2/docs/core/08_lifecycle.md index e69de29bb2d1..0e55ead7ecaf 100644 --- a/modules/angular2/docs/core/08_lifecycle.md +++ b/modules/angular2/docs/core/08_lifecycle.md @@ -0,0 +1,64 @@ +# Application LifeCycle + +Application LifeCycle describes when different lifecycle events occure during the lifetime of the application. As the Angular application executes, it is helpuful to undersand different phases of execution and the philosophy behind each. + +## Browser Event Processing + +At its core an Angular application is tightly bound to the browser execution/event loop. This means that an Angular application can only do work in response to a browser event. These events can be due to user input, server response, or scheduled timers. + +In order to know when the event when an even happens, the event needs to be registered inside an Angular Zone, which adds the lifecycle processing to the event. Events registered outside the Angular Zone will not be intercepted and hence will not have their bindings processed. + +One can use the Angular Zone to controll which events should have binding side effects and which should not just by controlling in which zone event registration took place. + +## Angular Zone Event Processing + +The event callback usually contains the work which mutates the application state, while the data-binding contains instructions how to project the mutated state back to the UI. + +The Angular Zone will automatically trigger the change detection at the end of each event. + + +## Change Detection + +Change Detection is a way of detecting changes to the application state and projecting these changes into the UI. The change detection starts at the root of the application and proceds to the children in the depth-first traversal. The change detection tree follows the View tree. + +When a change is detected it is delivered to the coresponding binding. This is either the element property or the property on the directive. + +If the directive has `onChange` method, then the `onChange` method is executed after all of the changes have been delivered to the directive. This gives the directive a chance to compute new values for child bindings (to child directives or elements) + +Finally if a directive has `onCheck` method, it is invoked, which gives the directive a chance to perform its own change detection. Usually used with structural checks. + +Angular's change detection is limited to the reference equality. Angular's change detection can not deep watch objects (known as structural changes). The reason for this is that structural changes are expensive. Furthermore the change delivery mechanism is usage specific. (i.e. `foreach` may want to have its changes deliverd in a animation compatible way, where as `class`-list may have more relaxed requriments.) In ordere to structuraly watch an on object the directive must use a custom structural watcher (common ones are provided) and invoke its `check` method from the `onCheck` lifecycle event. + + + +### Directed Acyclic Graph + +The change detection processes changes from the root to the child bindings in the depth first order. A change in parent binding, may change the application model such that a child binding may fire as a result. The parent to child flow of data is strict. The consequence of this is that the bindings form a directed (parent to child) acyclic (single pass, no stabilization) graph (DAG). This is in contrast to Angular v1.x where bindings could go in any direction (from child to parent) and they could form cycles. Cycles in the graph require multiple digest, and run the risk of not stabilizing after few iterations. This is strictly prohibited in Angular2 and is enforced in the development mode. + +The advantages of DAG is that for large applications the flow of data is easier to reason about, performance is a lot more predictable, and it allows us to disable change detection in some branches under some circumstaces further improving performance. + + + +## View Creation and Destruction + +While change detection is running, a binding may cause an Instantiator directive to create, destroy, or move a View in a ViewPort. + +Views have their own lifecycle methods which the directives can tage advantage of. A View goes through these changes. + +- *creation* - Instantiate new View from the ProtoView. This is relativly expensive operation which involves DOM cloning and locating of the Nodes which have bindings. +- *hydration* - Create associated directives for the View when the View is attached to the ViewPort. +- *dehydration* - View is removed from the ViewPort and the associated directives need to be destroyed. +- *cached* - A View is no longer in used, but it is cached so that a relativly expensive *creation* operation can be skipped in case someone needs a View again. +- *destruction* - View is released to GC if the cache is filled up. + + +# Summary + +A directive is notified of these lifecycle events. + +- `onHydrate()` - Right after the directive is created. +- Change Detection + - update bindings - A directive property (or property setter) is updated. + - `onChange()` - Called to let the directive know that all of the directive properties have been updated and that there are no more changes. + - `onCheck()` - Called after `onChange()` which allows the directive to perform structural changes as part of the change detection. +- `onDehydrate()` - Called to let the directive know that the associated View has been destroyed. \ No newline at end of file