From dd38ce6585b0e7ffa755f4c65d78ed90204729d1 Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Tue, 28 Feb 2012 12:14:47 -0800 Subject: docs(scope): rewrite --- .../dev_guide.mvc.understanding_controller.ngdoc | 2 +- .../guide/dev_guide.mvc.understanding_model.ngdoc | 2 +- .../content/guide/dev_guide.scopes.internals.ngdoc | 230 -------------- docs/content/guide/dev_guide.scopes.ngdoc | 35 --- .../dev_guide.scopes.understanding_scopes.ngdoc | 66 ----- .../guide/dev_guide.templates.databinding.ngdoc | 2 +- docs/content/guide/index.ngdoc | 13 +- docs/content/guide/scope.ngdoc | 330 +++++++++++++++++++++ docs/content/misc/started.ngdoc | 2 +- 9 files changed, 338 insertions(+), 344 deletions(-) delete mode 100644 docs/content/guide/dev_guide.scopes.internals.ngdoc delete mode 100644 docs/content/guide/dev_guide.scopes.ngdoc delete mode 100644 docs/content/guide/dev_guide.scopes.understanding_scopes.ngdoc create mode 100644 docs/content/guide/scope.ngdoc (limited to 'docs') diff --git a/docs/content/guide/dev_guide.mvc.understanding_controller.ngdoc b/docs/content/guide/dev_guide.mvc.understanding_controller.ngdoc index edaddf66..cfe223c6 100644 --- a/docs/content/guide/dev_guide.mvc.understanding_controller.ngdoc +++ b/docs/content/guide/dev_guide.mvc.understanding_controller.ngdoc @@ -3,7 +3,7 @@ @description In angular, a controller is a JavaScript function(type/class) that is used to augment instances of -angular {@link dev_guide.scopes Scope}, excluding the root scope. When you or angular create a new +angular {@link scope Scope}, excluding the root scope. When you or angular create a new child scope object via the {@link api/angular.module.ng.$rootScope.Scope#$new scope.$new} API , there is an option to pass in a controller as a method argument. This will tell angular to associate the controller with the new scope and to augment its behavior. diff --git a/docs/content/guide/dev_guide.mvc.understanding_model.ngdoc b/docs/content/guide/dev_guide.mvc.understanding_model.ngdoc index 06557b8d..b8c08198 100644 --- a/docs/content/guide/dev_guide.mvc.understanding_model.ngdoc +++ b/docs/content/guide/dev_guide.mvc.understanding_model.ngdoc @@ -7,7 +7,7 @@ either a single object representing one entity (for example, a model called "pho being an array of phones) or the entire data model for the application (all entities). In angular, a model is any data that is reachable as a property of an angular {@link -dev_guide.scopes Scope} object. The name of the property is the model identifier and the value is +scope Scope} object. The name of the property is the model identifier and the value is any JavaScript object (including arrays and primitives). The only requirement for a JavaScript object to be a model in angular is that the object must be diff --git a/docs/content/guide/dev_guide.scopes.internals.ngdoc b/docs/content/guide/dev_guide.scopes.internals.ngdoc deleted file mode 100644 index 090d5261..00000000 --- a/docs/content/guide/dev_guide.scopes.internals.ngdoc +++ /dev/null @@ -1,230 +0,0 @@ -@ngdoc overview -@name Developer Guide: Scopes: Scope Internals -@description - -## What is a scope? - -A scope is an execution context for {@link dev_guide.expressions expressions}. You can think of a -scope as a JavaScript object that has an extra set of APIs for registering change listeners and for -managing its own life cycle. In Angular's implementation of the model-view-controller design -pattern, a scope's properties comprise both the model and the controller methods. - - -### Scope characteristics -- Scopes provide APIs ({@link api/angular.module.ng.$rootScope.Scope#$watch $watch}) to observe model mutations. -- Scopes provide APIs ({@link api/angular.module.ng.$rootScope.Scope#$apply $apply}) to propagate any model changes -through the system into the view from outside of the "Angular realm" (controllers, services, -Angular event handlers). -- Scopes can be nested to isolate application components while providing access to shared model -properties. A scope (prototypically) inherits properties from its parent scope. -- In some parts of the system (such as controllers, services and directives), the scope is made -available as `this` within the given context. (Note: This api will change before 1.0 is released.) - - -### Root scope - -Every application has a root scope, which is the ancestor of all other scopes. - -### What is scope used for? - -{@link dev_guide.expressions Expressions} in the view are {@link api/angular.module.ng.$rootScope.Scope#$eval evaluated} -against the current scope. When HTML DOM elements are attached to a scope, expressions in those -elements are evaluated against the attached scope. - -There are two kinds of expressions: - -- Binding expressions, which are observations of property changes. Property changes are reflected -in the view during the {@link api/angular.module.ng.$rootScope.Scope#$digest digest cycle}. -- Action expressions, which are expressions with side effects. Typically, the side effects cause -execution of a method in a controller in response to a user action, such as clicking on a button. - - -### Scope inheritance - -A scope (prototypically) inherits properties from its parent scope. Since a given property may not -reside on a child scope, if a property read does not find the property on a scope, the read will -recursively check the parent scope, grandparent scope, etc. all the way to the root scope before -defaulting to undefined. - -{@link guide/directive directives} associated with elements -(ngController, ngRepeat, ngInclude, etc.) create new child scopes that inherit properties from -the current parent scope. Any code in Angular is free to create a new scope. Whether or not your -code does so is an implementation detail of the directive, that is, you can decide when or if this -happens. Inheritance typically mimics HTML DOM element nesting, but does not do so with the same -granularity. - -A property write will always write to the current scope. This means that a write can hide a parent -property within the scope it writes to, as shown in the following example. - -
-it('should inherit properties', inject(function($rootScope)) {
- var root = $rootScope;
- var child = root.$new();
-
- root.name = 'angular';
- expect(child.name).toEqual('angular');
- expect(root.name).toEqual('angular');
-
- child.name = 'super-heroic framework';
- expect(child.name).toEqual('super-heroic framework');
- expect(root.name).toEqual('angular');
-});
-
-
-
-### Scope life cycle
-1. **Creation**
-
- * The root scope is created by the {@link api/angular.module.ng.$rootScope $rootScope} service.
- * To create a child scopes, you should call {@link api/angular.module.ng.$rootScope.Scope#$new parentScope.$new()}.
-
-2. **Watcher registration**
-
- Watcher registration can happen at any time and on any scope (root or child) via {@link
-api/angular.module.ng.$rootScope.Scope#$watch scope.$watch()} API.
-
-3. **Model mutation**
-
- For mutations to be properly observed, you should make them only within the execution of the
-function passed into {@link api/angular.module.ng.$rootScope.Scope#$apply scope.$apply()} call. (Angular apis do this
-implicitly, so no extra `$apply` call is needed when doing synchronous work in controllers, or
-asynchronous work with {@link api/angular.module.ng.$http $http} or {@link api/angular.module.ng.$defer
-$defer} services.
-
-4. **Mutation observation**
-
- At the end of each `$apply` call {@link api/angular.module.ng.$rootScope.Scope#$digest $digest} cycle is started on
-the root scope, which then propagates throughout all child scopes.
-
- During the `$digest` cycle, all `$watch-ers` expressions or functions are checked for model
-mutation and if a mutation is detected, the `$watch-er` listener is called.
-
-5. **Scope destruction**
-
- When child scopes are no longer needed, it is the responsibility of the child scope creator to
-destroy them via {@link api/angular.module.ng.$rootScope.Scope#$destroy scope.$destroy()} API. This will stop
-propagation of `$digest` calls into the child scope and allow for memory used by the child scope
-models to be reclaimed by the garbage collector.
-
- The root scope can't be destroyed via the `$destroy` API. Instead, it is enough to remove all
-references from your application to the scope object and garbage collector will do its magic.
-## Scopes in Angular applications
-To understand how Angular applications work, you need to understand how scopes work within an
-application. This section describes the typical life cycle of an application so you can see how
-scopes come into play throughout and get a sense of their interactions.
-### How scopes interact in applications
-
-1. At application compile time, a root scope is created and is attached to the root `` DOM
-element.
-2. During the compilation phase, the {@link dev_guide.compiler compiler} matches {@link
-guide/directive directives} against the DOM template. The directives
-usually fall into one of two categories:
- - Observing {@link guide/directive directives}, such as double-curly
- expressions `{{expression}}`, register listeners using the {@link
- api/angular.module.ng.$rootScope.Scope#$watch $watch()} method. This type of directive needs to
- be notified whenever the expression changes so that it can update the view.
- - Listener directives, such as {@link api/angular.module.ng.$compileProvider.directive.ngClick
- ngClick}, register a listener with the DOM. When the DOM listener fires, the directive executes
- the associated expression and updates the view using the {@link
- api/angular.module.ng.$rootScope.Scope#$apply $apply()} method.
-3. When an external event (such as a user action, timer or XHR) is received, the associated {@link
-dev_guide.expressions expression} must be applied to the scope through the {@link
-api/angular.module.ng.$rootScope.Scope#$apply $apply()} method so that all listeners are updated correctly.
-
-
-### Directives that create scopes
-In most cases, {@link guide/directive directives} and scopes interact but do not create new
-instances of scope. However, some directives, such as {@link api/angular.module.ng.$compileProvider.directive.ngController
-ngController} and {@link api/angular.module.ng.$compileProvider.directive.ngRepeat ngRepeat}, create new child scopes using
-the {@link api/angular.module.ng.$rootScope.Scope#$new $new()} method and then attach the child scope to the
-corresponding DOM element. You can retrieve a scope for any DOM element by using an
-`angular.element(aDomElement).scope()` method call.)
-
-
-### Controllers and scopes
-Scopes and controllers interact with each other in the following situations:
- - Controllers use scopes to expose controller methods to templates (see {@link
-api/angular.module.ng.$compileProvider.directive.ngController ngController}).
- - Controllers define methods (behavior) that can mutate the model (properties on the scope).
- - Controllers may register {@link api/angular.module.ng.$rootScope.Scope#$watch watches} on the model. These watches
-execute immediately after the controller behavior executes, but before the DOM gets updated.
-
-See the {@link dev_guide.mvc.understanding_controller controller docs} for more information.
-
-### Updating scope properties
-You can update a scope by calling its {@link api/angular.module.ng.$rootScope.Scope#$apply $apply()} method with an
-expression or a function as the function argument. However it is typically not necessary to do this
-explicitly. In most cases, angular intercepts all external events (such as user interactions, XHRs,
-and timers) and wraps their callbacks into the `$apply()` method call on the scope object for you
-at the right time. The only time you might need to call `$apply()` explicitly is when you create
-your own custom asynchronous widget or service.
-
-The reason it is unnecessary to call `$apply()` from within your controller functions when you use
-built-in angular widgets and services is because your controllers are typically called from within
-an `$apply()` call already.
-
-When a user inputs data, angularized widgets invoke `$apply()` on the current scope and evaluate an
-angular expression or execute a function on this scope. Afterwards `$apply` will trigger `$digest`
-call on the root scope, to propagate your changes through the entire system, which results in
-$watch-ers firing and view getting updated. Similarly, when a request to fetch data from a server
-is made and the response comes back, the data is written into the model (scope) within an $apply,
-which then pushes updates through to the view and any other dependents.
-
-A widget that creates scopes (such as {@link api/angular.module.ng.$compileProvider.directive.ngRepeat ngRepeat}) via `$new`,
-doesn't need to worry about propagating the `$digest` call from the parent scope to child scopes.
-This happens automatically.
-
-## Scopes in unit-testing
-You can create scopes, including the root scope, in tests by having the $rootScope injected into
-your spec. This allows you to mimic the run-time environment and have full control over
-the life cycle of the scope so that you can assert correct model transitions. Since these scopes
-are created outside the normal compilation process, their life cycles must be managed by the test.
-
-### Using scopes in unit-testing
-The following example demonstrates how the scope life cycle needs to be manually triggered from
-within the unit-tests.
-
-
- // example of a test
- it('should trigger a watcher', inject(function($rootScope) {
- var scope = $rootScope;
- scope.$watch('name', function(name) {
- scope.greeting = 'Hello ' + name + '!';
- });
-
- scope.name = 'angular';
- // The watch does not fire yet since we have to manually trigger the digest phase.
- expect(scope.greeting).toEqual(undefined);
-
- // manually trigger digest phase from the test
- scope.$digest();
- expect(scope.greeting).toEqual('Hello Angular!');
- }
-
-
-
-### Dependency injection in Tests
-
-When you find it necessary to inject your own mocks in your tests, use a scope to override the
-service instances, as shown in the following example.
-
-
-it('should allow override of providers', inject(
- function($provide) {
- $provide.value('$location', {mode:'I am a mock'});
- },
- function($location){
- expect($location.mode).toBe('I am a mock');
- }
-)};
-
-
-## Related Topics
-
-* {@link dev_guide.scopes Angular Scope Objects}
-* {@link dev_guide.scopes.understanding_scopes Understanding Scopes}
-
-## Related API
-
-* {@link api/angular.module.ng.$rootScope.Scope Angular Scope API}
-
diff --git a/docs/content/guide/dev_guide.scopes.ngdoc b/docs/content/guide/dev_guide.scopes.ngdoc
deleted file mode 100644
index 6ddbcae4..00000000
--- a/docs/content/guide/dev_guide.scopes.ngdoc
+++ /dev/null
@@ -1,35 +0,0 @@
-@ngdoc overview
-@name Developer Guide: Scopes
-@description
-
-
-An Angular scope is a JavaScript object with additional APIs useful for watching property changes,
-Angular scope is the model in Model-View-Controller paradigm. Instances of scope serve as the
-context within which all {@link dev_guide.expressions expressions} get evaluated.
-
-You can think of Angular scope objects as the medium through which the model, view, and controller
-communicate. Scopes are linked during the compilation process with the view. This linkage provides
-the contexts in which Angular creates data-bindings between the model and the view.
-
-In addition to providing the context in which data is evaluated, Angular scope objects watch for
-model changes. The scope objects also notify all components interested in any model changes (for
-example, functions registered through {@link api/angular.module.ng.$rootScope.Scope#$watch $watch}, bindings created by
-{@link api/angular.module.ng.$compileProvider.directive.ngBind ngBind}, or HTML input elements).
-
-Angular scope objects:
-
-* Link the model, controller and view template together.
-* Provide the mechanism to watch for model changes ({@link api/angular.module.ng.$rootScope.Scope#$watch $watch}).
-* Apply model changes to the system ({@link api/angular.module.ng.$rootScope.Scope#$apply $apply}).
-* Provide the context in which expressions are evaluated ({@link api/angular.module.ng.$rootScope.Scope#$eval $eval}).
-
-
-## Related Topics
-
-* {@link dev_guide.scopes.understanding_scopes Understanding Scopes}
-* {@link dev_guide.scopes.internals Scopes Internals}
-
-## Related API
-
-* {@link api/angular.module.ng.$rootScope.Scope Angular Scope API}
-
diff --git a/docs/content/guide/dev_guide.scopes.understanding_scopes.ngdoc b/docs/content/guide/dev_guide.scopes.understanding_scopes.ngdoc
deleted file mode 100644
index aeab3191..00000000
--- a/docs/content/guide/dev_guide.scopes.understanding_scopes.ngdoc
+++ /dev/null
@@ -1,66 +0,0 @@
-@ngdoc overview
-@name Developer Guide: Scopes: Understanding Scopes
-@description
-
-Angular automatically creates a root scope during initialization, and attaches it to the page's
-root DOM element (usually ``). The root scope object, along with any of its child scope
-objects, serves as the infrastructure on which your data model is built. The data model (JavaScript
-objects, arrays, or primitives) is attached to angular scope properties. Angular binds the property
-values to the DOM where bindings are specified in the template. Angular attaches any controller
-functions you have created to their respective scope objects.
-
-
-
-Angular scopes can be nested, so a child scope has a parent scope upstream in the DOM. When you
-display an angular expression in the view, angular walks the DOM tree looking in the closest
-attached scope object for the specified data. If it doesn't find the data in the closest attached
-scope, it looks further up the scope hierarchy until it finds the data.
-
-A child scope object inherits properties from its parents. For example, in the following snippet of
-code, observe how the value of `name` changes, based on the HTML element it is displayed in:
-
-Name={{name}}
-
-
-
-## Related Topics
-
-* {@link dev_guide.scopes Angular Scope Objects}
-* {@link dev_guide.scopes.internals Scopes Internals}
-
-## Related API
-
-* {@link api/angular.module.ng.$rootScope.Scope Angular Scope API}
diff --git a/docs/content/guide/dev_guide.templates.databinding.ngdoc b/docs/content/guide/dev_guide.templates.databinding.ngdoc
index 7f480a6a..ebd9a1e6 100644
--- a/docs/content/guide/dev_guide.templates.databinding.ngdoc
+++ b/docs/content/guide/dev_guide.templates.databinding.ngdoc
@@ -34,5 +34,5 @@ isolation without the view and the related DOM/browser dependency.
## Related Topics
-* {@link dev_guide.scopes Angular Scopes}
+* {@link scope Angular Scopes}
* {@link dev_guide.templates Angular Templates}
diff --git a/docs/content/guide/index.ngdoc b/docs/content/guide/index.ngdoc
index 377fdb97..04b02a49 100644
--- a/docs/content/guide/index.ngdoc
+++ b/docs/content/guide/index.ngdoc
@@ -2,7 +2,7 @@
@name Developer Guide
@description
-Welcome to the angular Developer Guide. If you are here to learn the details of how to use angular
+Welcome to the angular Developer Guide. If you are here to learn the details of how to use angular
to develop web apps, you've come to the right place.
If you are completely or relatively unfamiliar with angular, you may want to check out one or both
@@ -13,7 +13,7 @@ of the following documents before returning here to the Developer Guide:
+ it('should say hello', function() {
+ var scopeMock = {};
+ var cntl = new MyController(scopeMock);
+
+ // Assert that username is pre-filled
+ expect(scopeMock.username).toEqual('World');
+
+ // Assert that we read new username and greet
+ scopeMock.username = 'angular';
+ scopeMock.sayHello();
+ expect(scopeMock.greeting).toEqual('Hello angular!');
+ });
+
+
+
+## Scope Hierarchies
+
+Each Angular application has exactly one {@link api/angular.module.ng.$rootScope root scope}, but
+may have several child scopes.
+
+The application can have multiple scopes, because some {@link guide/directive directives} create
+new child scopes (refer to directive documentation to see which directives create new scopes).
+When new scopes are created, they are added as children of their parent scope. This creates a tree
+structure which parallels the DOM where they're attached
+
+When Angular evaluates `{{username}}`, it first looks at the scope associated with the given
+element for the `username` property. If no such property is found, it searches the parent scope
+and so on until the root scope is reached. In JavaScript this behavior is known as prototypical
+inheritance, and child scopes prototypically inherit from their parents.
+
+This example illustrates scopes in application, and prototypical inheritance of properties.
+
+