docs(guide/tutorial/misc): sync with google docs

This commit is contained in:
Igor Minar 2011-09-01 15:33:48 -07:00
parent 8d11db0757
commit bc6e0cc954
10 changed files with 206 additions and 71 deletions

View file

@ -21,7 +21,6 @@ exceptions
* {@link angular.service.$resource $resource } - Creates objects for interacting with RESTful
server-side data sources
* {@link angular.service.$route $route } - Provides deep-linking services
* {@link angular.service.$updateView $updateView } - Queues view updates
* {@link angular.service.$window $window } - References the browsers `window` object
* {@link angular.service.$xhr $xhr} - Generates an XHR request.

View file

@ -15,12 +15,11 @@ explicitly.
<!doctype html>
<html xmlns:ng="http://angularjs.org">
<head>
<script type="text/javascript" src="http://code.angularjs.org/angular.js"
ng:autobind></script>
<script type="text/javascript">
(angular.element(document).ready(function() {
<script src="http://code.angularjs.org/angular.js"></script>
<script>
angular.element(document).ready(function() {
angular.compile(document)();
})(document);
});
</script>
</head>
<body>

View file

@ -0,0 +1,124 @@
@ngdoc overview
@name Developer Guide: i18n and l10n
@description
# I18n and L10n in AngularJS
**What is i18n and l10n?**
Internationalization, abbreviated i18n, is the process of developing products in such a way that
they can be localized for languages and cultures easily. Localization, abbreviated l10n, is the
process of adapting applications and text to enable their usability in a particular cultural or
linguistic market. For application developers, internationalizing an application means abstracting
all of the strings and other locale-specific bits (such as date or currency formats) out of the
application. Localizing an application means providing translations and localized formats for the
abstracted bits.
**What level of support for i18n/l10n is currently in Angular?**
Currently, Angular supports i18n/l10n for {@link
http://docs.angularjs.org/#!/api/angular.filter.date datetime}, {@link
http://docs.angularjs.org/#!/api/angular.filter.number number} and {@link
http://docs.angularjs.org/#!/api/angular.filter.currency currency} filters.
Additionally, Angular supports localizable pluralization support provided by the {@link
api/angular.widget.ng:pluralize ng:pluralize widget}.
All localizable Angular components depend on locale-specific rule sets managed by the {@link
api/angular.service.$locale $locale service}.
For readers who want to jump straight into examples, we have a few web pages that showcase how to
use Angular filters with various locale rule sets. You can find these examples either on {@link
https://github.com/angular/angular.js/tree/master/i18n/e2e Github} or in the i18n/e2e folder of
Angular development package.
**What is a locale id?**
A locale is a specific geographical, political, or cultural region. The most commonly used locale
ID consists of two parts: language code and country code. For example, en-US, en-AU, zh-CN are all
valid locale IDs that have both language codes and country codes. Because specifying a country code
in locale ID is optional, locale IDs such as en, zh, and sk are also valid. See the {@link
http://userguide.icu-project.org/locale ICU } website for more information about using locale IDs.
**Supported locales in Angular**
Angular separates number and datetime format rule sets into different files, each file for a
particular locale. You can find a list of currently supported locales {@link
https://github.com/angular/angular.js/tree/master/i18n/locale here}
# Providing locale rules to Angular
There are two approaches to providing locale rules to Angular:
**1. Pre-bundled rule sets**
You can pre-bundle the desired locale file with Angular by concatenating the content of the
locale-specific file to the end of `angular.js` or `angular.min.js` file.
For example on *nix, to create a an angular.js file that contains localization rules for german
locale, you can do the following:
`cat angular.js i18n/angular-locale_de-ge.js > angular_de-ge.js`
When the application containing `angular_de-ge.js` script instead of the generic angular.js script
starts, Angular is automatically pre-configured with localization rules for the german locale.
**2. Including locale js script in index.html page**
You can also include the locale specific js file in the index.html page. For example, if one client
requires German locale, you would serve index_de-ge.html which will look something like this:
<pre>
<html>
<head>
….
<script src="angular.js" ng:autobind></script>
<script src="i18n/angular-locale_de-ge.js"></script>
….
</head>
</html>
</pre>
**Comparison of the two approaches**
Both approaches described above requires you to prepare different index.html pages or js files for
each locale that your app may be localized into. You also need to configure your server to serve
the correct file that correspond to the desired locale.
However, the second approach (Including locale js script in index.html page) is likely to be slower
because an extra script needs to be loaded.
# "Gotchas"
**Currency symbol "gotcha"**
Angular's {@link http://docs.angularjs.org/#!/api/angular.filter.currency currency filter} allows
you to use the default currency symbol from the {@link api/angular.service.$locale locale service},
or you can provide the filter with a custom currency symbol. If your app will be used only in one
locale, it is fine to rely on the default currency symbol. However, if you anticipate that viewers
in other locales might use your app, you should provide your own currency symbol to make sure the
actual value is understood.
For example, if you want to display account balance of 1000 dollars with the following binding
containing currency filter: `{{ 1000 | currency }}`, and your app is currently in en-US locale.
'$1000.00' will be shown. However, if someone in a different local (say, Japan) views your app, her
browser will specify the locale as ja, and the balance of '¥1000.00' will be shown instead. This
will really upset your client.
In this case, you need to override the default currency symbol by providing the {@link
http://docs.angularjs.org/#!/api/angular.filter.currency currency filter} with a currency symbol as
a parameter when you configure the filter, for example, {{ 1000 | currency:"USD$"}}. This way,
Angular will always show a balance of 'USD$1000' and disregard any locale changes.
**Translation length "gotcha"**
Keep in mind that translated strings/datetime formats can vary greatly in length. For example,
`June 3, 1977` will be translated to Spanish as `3 de junio de 1977`. There are bound to be other
more extreme cases. Hence, when internationalizing your apps, you need to apply CSS rules
accordingly and do thorough testing to make sure UI components do not overlap.
**Timezones**
Keep in mind that Angular datetime filter uses the time zone settings of the browser. So the same
application will show different time information depending on the time zone settings of the
computer that the application is running on. Neither Javascript nor Angular currently supports
displaying the date with a timezone specified by the developer.

View file

@ -1,4 +1,3 @@
@workInProgress
@ngdoc overview
@name Developer Guide: Scopes: Scope Internals
@description
@ -12,14 +11,14 @@ pattern, a scope's properties comprise both the model and the controller methods
### Scope characteristics
- Scopes provide APIs ($watch and $observe) to observe model mutations.
- Scopes provide APIs ($apply) to propagate any model changes through the system into the view from
outside of the "Angular realm" (controllers, services, Angular event handlers).
- Scopes provide APIs ({@link api/angular.scope.$watch $watch}) to observe model mutations.
- Scopes provide APIs ({@link api/angular.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 functionality will change before 1.0 is
released.)
available as `this` within the given context. (Note: This api will change before 1.0 is released.)
### Root scope
@ -30,13 +29,14 @@ $service} property, and initializing the services.
### What is scope used for?
{@link dev_guide.expressions Expressions} in the view are evaluated against the current scope. When
HTML DOM elements are attached to a scope, expressions in those elements are evaluated against the
attached scope.
{@link dev_guide.expressions Expressions} in the view are {@link api/angular.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.scope.$flush flush cycle}.
in the view during the {@link api/angular.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.
@ -72,7 +72,42 @@ expect(root.name).toEqual('angular');
</pre>
### Scope life cycle
1. **Creation**
* You can create the root scope via {@link api/angular.scope angular.scope()}.
* To create a child scopes, you should call {@link api/angular.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.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.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.service.$xhr $xhr} or {@link api/angular.service.$defer
$defer} services.
4. **Mutation observation**
At the end of each `$apply` call {@link api/angular.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.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
@ -88,9 +123,9 @@ element.
api/angular.directive directives} against the DOM template. The directives usually fall into one of
two categories:
- Observing {@link api/angular.directive directives}, such as double-curly expressions
`{{expression}}`, register listeners using the {@link api/angular.scope.$observe $observe()}
method. This type of directive needs to be notified whenever the expression changes so that it can
update the view.
`{{expression}}`, register listeners using the {@link api/angular.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.directive.ng:click ng:click}, 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.scope.$apply $apply()} method.
@ -119,39 +154,33 @@ execute immediately after the controller behavior executes, but before the DOM g
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.scope.$eval $eval()} method, but usually
you do not have to do this explicitly. In most cases, angular intercepts all external events (such
as user interactions, XHRs, and timers) and calls the `$eval()` method on the scope object for you
at the right time. The only time you might need to call `$eval()` explicitly is when you create
your own custom widget or service.
You can update a scope by calling its {@link api/angular.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 `$eval()` from within your controller functions when you use
built-in angular widgets and services is because a change in the data model triggers a call to the
`$eval()` method on the scope object where the data model changed.
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 copy the data to the appropriate scope and then call
the `$eval()` method on the root scope to update the view. It works this way because scopes are
inherited, and a child scope `$eval()` overrides its parent's `$eval()` method. Updating the whole
page requires a call to `$eval()` on the root scope as `$root.$eval()`. Similarly, when a request
to fetch data from a server is made and the response comes back, the data is written into the model
and then `$eval()` is called to push updates through to the view and any other dependents.
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.widget.@ng:repeat ng:repeat}) is
responsible for forwarding `$eval()` calls from the parent to those child scopes. That way, calling
`$eval()` on the root scope will update the whole page. This creates a spreadsheet-like behavior
for your app; the bound views update immediately as the user enters data.
A widget that creates scopes (such as {@link api/angular.widget.@ng:repeat ng:repeat}) 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 using the {@link api/angular.scope} API.
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.
There is a key difference between the way scopes are called in Angular applications and in Angular
tests. In tests, the {@link api/angular.service.$updateView $updateView} calls the {@link
api/angular.scope.$flush $flush()} method synchronously.(This is in contrast to the asynchronous
calls used for applications.) Because test calls to scopes are synchronous, your tests are simpler
to write.
You can create scopes, including the root scope, in tests using the {@link api/angular.scope
angular.scope()} API. 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
@ -181,7 +210,7 @@ service instances, as shown in the following example.
<pre>
var myLocation = {};
var scope = angular.scope(null, {$location: myLocation});
var scope = angular.scope(angular.service, {$location: myLocation});
expect(scope.$service('$location')).toEqual(myLocation);
</pre>

View file

@ -1,4 +1,3 @@
@workInProgress
@ngdoc overview
@name Developer Guide: Scopes
@description
@ -20,9 +19,9 @@ example, functions registered through {@link api/angular.scope.$watch $watch}, b
Angular scope objects:
* Link the model, controller and view template together.
* Provide the mechanism to watch for model changes ({@link api/angular.scope.$watch}).
* Notify interested components when the model changes ({@link api/angular.scope.$eval}).
* Provide the context in which expressions are evaluated.
* Provide the mechanism to watch for model changes ({@link api/angular.scope.$watch $watch}).
* Apply model changes to the system ({@link api/angular.scope.$apply $apply}).
* Provide the context in which expressions are evaluated ({@link api/angular.scope.$eval $eval}).
## Related Topics

View file

@ -1,4 +1,3 @@
@workInProgress
@ngdoc overview
@name Developer Guide: Scopes: Understanding Scopes
@description
@ -27,7 +26,7 @@ code, observe how the value of `name` changes, based on the HTML element it is d
Name = {{name}}!
</li>
</ul>
<pre>Name={{name}}</pre>
<pre>Name={{name}}</pre>
</doc:source>
<doc:scenario>
it('should override the name property', function() {

View file

@ -45,7 +45,7 @@ angular.service('batchLog', function($defer, $log) {
* template via the batchLog service.
*/
angular.service('routeTemplateMonitor', function($route, batchLog) {
$route.onChange(function() {
this.$on('$afterRouteChange', function() {
batchLog($route.current ? $route.current.template : null);
});
}, {$inject: ['$route', 'batchLog'], $eager: true});

View file

@ -93,6 +93,7 @@ pre-packaged bundle.
* install q: `npm install q`
* install qq: `npm install qq`
* install q-fs: `npm install q-fs`
* install jasmine-node: `npm install jasmine`

View file

@ -146,7 +146,7 @@ __`app/partials/phone-list.html`:__
We also added a placeholder template for the phone details view:
__`app/partials/phone-list.html`:__
__`app/partials/phone-detail.html`:__
<pre>
TBD: detail view for {{params.phoneId}}
</pre>

View file

@ -34,7 +34,6 @@ function createScope(providers, instanceCache) {
/**
* @workInProgress
* @ngdoc function
* @name angular.scope
*
@ -103,7 +102,6 @@ function Scope() {
}
/**
* @workInProgress
* @ngdoc property
* @name angular.scope.$id
* @returns {number} Unique scope ID (monotonically increasing alphanumeric sequence) useful for
@ -111,7 +109,6 @@ function Scope() {
*/
/**
* @workInProgress
* @ngdoc property
* @name angular.scope.$service
* @function
@ -125,14 +122,12 @@ function Scope() {
*/
/**
* @workInProgress
* @ngdoc property
* @name angular.scope.$root
* @returns {Scope} The root scope of the current scope hierarchy.
*/
/**
* @workInProgress
* @ngdoc property
* @name angular.scope.$parent
* @returns {Scope} The parent scope of the current scope.
@ -141,7 +136,6 @@ function Scope() {
Scope.prototype = {
/**
* @workInProgress
* @ngdoc function
* @name angular.scope.$new
* @function
@ -196,7 +190,6 @@ Scope.prototype = {
},
/**
* @workInProgress
* @ngdoc function
* @name angular.scope.$watch
* @function
@ -283,7 +276,6 @@ Scope.prototype = {
},
/**
* @workInProgress
* @ngdoc function
* @name angular.scope.$digest
* @function
@ -389,7 +381,6 @@ Scope.prototype = {
},
/**
* @workInProgress
* @ngdoc function
* @name angular.scope.$destroy
* @function
@ -418,7 +409,6 @@ Scope.prototype = {
},
/**
* @workInProgress
* @ngdoc function
* @name angular.scope.$eval
* @function
@ -452,7 +442,6 @@ Scope.prototype = {
},
/**
* @workInProgress
* @ngdoc function
* @name angular.scope.$evalAsync
* @function
@ -480,7 +469,6 @@ Scope.prototype = {
},
/**
* @workInProgress
* @ngdoc function
* @name angular.scope.$apply
* @function
@ -534,7 +522,6 @@ Scope.prototype = {
},
/**
* @workInProgress
* @ngdoc function
* @name angular.scope.$on
* @function
@ -569,7 +556,6 @@ Scope.prototype = {
/**
* @workInProgress
* @ngdoc function
* @name angular.scope.$emit
* @function
@ -620,7 +606,6 @@ Scope.prototype = {
/**
* @workInProgress
* @ngdoc function
* @name angular.scope.$broadcast
* @function