docs(guide/filter): Refactor filter guide docs

This refactors the filter guide docs into a single file.
Also removes out of date references to the fact that Angular used to enhance Arrays while evaluating expressions.
This commit is contained in:
Tobias Bosch 2013-11-07 14:14:57 -08:00
parent ed8640b964
commit 3662140201
18 changed files with 138 additions and 193 deletions

View file

@ -9,7 +9,7 @@ The documentation is organized into **modules** which contain various components
These components are directives, services, filters, providers, types, global APIs and testing mocks.
<div class="alert alert-info">
**Angular Namspaces `$` and `$$`**
**Angular Namespaces `$` and `$$`**
To prevent accidental name collisions with your code,
Angular prefixes names of public objects with `$` and names of private objects with `$$`.

View file

@ -86,7 +86,7 @@ in the rest of the documentation.
Applied to the example above, the markup directs Angular to "take the data we got from the input widgets
and multiply them together".
The example above also contains a <a name="filter">"{@link dev_guide.templates.filters filter}"</a>.
The example above also contains a <a name="filter">"{@link filter filter}"</a>.
A filter formats the value of an expression for display to the user.
In the example above, the filter {@link api/ng.filter:currency `currency`} formats a number
into an output that looks like money.
@ -144,7 +144,7 @@ allow to enter and calculate the costs in different currencies and also pay the
<span ng-repeat="c in invoice.currencies">
{{invoice.total(c) | currency:c}}
</span>
<button ng-click="invoice.pay()">Pay</button>
<button class="btn" ng-click="invoice.pay()">Pay</button>
</div>
</div>
</file>
@ -244,7 +244,7 @@ Let's refactor our example and move the currency conversion into a service in an
<span ng-repeat="c in invoice.currencies">
{{invoice.total(c) | currency:c}}
</span>
<button ng-click="invoice.pay()">Pay</button>
<button class="btn" ng-click="invoice.pay()">Pay</button>
</div>
</div>
</file>
@ -370,7 +370,7 @@ The following example shows how this is done with Angular:
<span ng-repeat="c in invoice.currencies">
{{invoice.total(c) | currency:c}}
</span>
<button ng-click="invoice.pay()">Pay</button>
<button class="btn" ng-click="invoice.pay()">Pay</button>
</div>
</div>
</file>

View file

@ -109,7 +109,7 @@ logic. Angular offers {@link databinding databinding} for automatic DOM manipula
you have to perform your own manual DOM manipulation, encapsulate the presentation logic in
{@link guide/directive directives}.
- Input formatting — Use {@link forms angular form controls} instead.
- Output filtering — Use {@link dev_guide.templates.filters angular filters} instead.
- Output filtering — Use {@link filter angular filters} instead.
- Sharing stateless or stateful code across Controllers — Use {@link dev_guide.services angular
services} instead.
- Managing the life-cycle of other components (for example, to create service instances).

View file

@ -1,60 +0,0 @@
@ngdoc overview
@name Developer Guide: Templates: Filters: Creating Angular Filters
@description
Writing your own filter is very easy: just register a new filter (injectable) factory function with
your module. This factory function should return a new filter function which takes the input value
as the first argument. Any filter arguments are passed in as additional arguments to the filter
function.
The following sample filter reverses a text string. In addition, it conditionally makes the
text upper-case.
<doc:example module="MyReverseModule">
<doc:source>
<script>
angular.module('MyReverseModule', []).
filter('reverse', function() {
return function(input, uppercase) {
var out = "";
for (var i = 0; i < input.length; i++) {
out = input.charAt(i) + out;
}
// conditional based on optional argument
if (uppercase) {
out = out.toUpperCase();
}
return out;
}
});
function Ctrl($scope) {
$scope.greeting = 'hello';
}
</script>
<div ng-controller="Ctrl">
<input ng-model="greeting" type="greeting"><br>
No filter: {{greeting}}<br>
Reverse: {{greeting|reverse}}<br>
Reverse + uppercase: {{greeting|reverse:true}}<br>
</div>
</doc:source>
<doc:scenario>
it('should reverse greeting', function() {
expect(binding('greeting|reverse')).toEqual('olleh');
input('greeting').enter('ABC');
expect(binding('greeting|reverse')).toEqual('CBA');
});
</doc:scenario>
</doc:example>
## Related Topics
* {@link dev_guide.templates.filters Understanding Angular Filters}
* {@link compiler Angular HTML Compiler}
## Related API
* {@link api/ng.$filter Angular Filter API}

View file

@ -1,23 +0,0 @@
@ngdoc overview
@name Developer Guide: Templates: Understanding Angular Filters
@description
Angular filters format data for display to the user.
For example, you might have a data object that needs to be formatted according to the locale before
displaying it to the user. You can pass expressions through a chain of filters like this:
name | uppercase
The expression evaluator simply passes the value of name to
{@link api/ng.filter:uppercase uppercase filter}.
## Related Topics
* {@link dev_guide.templates.filters.using_filters Using Angular Filters}
* {@link dev_guide.templates.filters.creating_filters Creating Angular Filters}
## Related API
* {@link api/ng.$filter Angular Filter API}

View file

@ -1,44 +0,0 @@
@ngdoc overview
@name Developer Guide: Templates: Filters: Using Angular Filters
@description
Filters can be part of any {@link api/ng.$rootScope.Scope} evaluation but are typically used to format
expressions in bindings in your templates:
{{ expression | filter }}
Filters typically transform the data to a new data type, formatting the data in the process.
Filters can also be chained, and can take optional arguments.
You can chain filters using this syntax:
{{ expression | filter1 | filter2 }}
You can also pass colon-delimited arguments to filters, for example, to display the number 123 with
2 decimal points:
123 | number:2
Use the same syntax for multiple arguments:
myArray | orderBy:'timestamp':true
Here are some examples that show values before and after applying different filters to an
expression in a binding:
* No filter: `{{1234.5678}}` => `1234.5678`
* Number filter: `{{1234.5678|number}}` => `1,234.57`. Notice the "," and rounding to two
significant digits.
* Filter with arguments: `{{1234.5678|number:5}}` => `1,234.56780`. Filters can take optional
arguments, separated by colons in a binding. For example, the "number" filter takes a number
argument that specifies how many digits to display to the right of the decimal point.
## Related Topics
* {@link dev_guide.templates.filters Understanding Angular Filters}
* {@link dev_guide.templates.filters.creating_filters Creating Angular Filters}
## Related API
* {@link api/ng.$filter Angular Filter API}

View file

@ -259,7 +259,7 @@ Notice that the test is not only much shorter but it is easier to follow what is
that such a test tells a story, rather then asserting random bits which don't seem to be related.
## Filters
{@link api/ng.$filter Filters} are functions which transform the data into user readable
{@link api/ng.$filterProvider Filters} are functions which transform the data into user readable
format. They are important because they remove the formatting responsibility from the application
logic, further simplifying the application logic.

View file

@ -4,12 +4,11 @@
Expressions are JavaScript-like code snippets that are usually placed in bindings such as `{{
expression }}`. Expressions are processed by the {@link api/ng.$parse $parse}
service.
service. Expressions are often post processed using {@link filter filters} to create a more user-friendly format.
For example, these are all valid expressions in angular:
* `1+2`
* `3*10 | currency`
* `user.name`
@ -29,9 +28,6 @@ You can think of Angular expressions as JavaScript expressions with following di
* **No Control Flow Statements:** you cannot do any of the following in angular expression:
conditionals, loops, or throw.
* **Filters:** you can pass result of expression evaluations through filter chains. For example
to convert date object into a local specific human-readable format.
If, on the other hand, you do want to run arbitrary JavaScript code, you should make it a
controller method and call the method. If you want to `eval()` an angular expression from
JavaScript, use the {@link api/ng.$rootScope.Scope#methods_$eval `$eval()`} method.
@ -150,37 +146,3 @@ You cannot write a control flow statement in an expression. The reason behind th
Angular philosophy that application logic should be in controllers, not in the view. If you need a
conditional, loop, or to throw from a view expression, delegate to a JavaScript method instead.
## Filters
When presenting data to the user, you might need to convert the data from its raw format to a
user-friendly format. For example, you might have a data object that needs to be formatted
according to the locale before displaying it to the user. You can pass expressions through a chain
of filters like this:
name | uppercase
The expression evaluator simply passes the value of name to {@link
api/ng.filter:uppercase `uppercase`} filter.
Chain filters using this syntax:
value | filter1 | filter2
You can also pass colon-delimited arguments to filters, for example, to display the number 123
with 2 decimal points:
123 | number:2
# The $
You might be wondering, what is the significance of the $ prefix? It is simply a prefix that
angular uses, to differentiate its API names from others. If angular didn't use $, then evaluating
`a.length()` would return undefined because neither a nor angular define such a property.
Consider that in a future version of Angular we might choose to add a length method, in which case
the behavior of the expression would change. Worse yet, you, the developer, could create a length
property and then we would have a collision. This problem exists because Angular augments existing
objects with additional behavior. By prefixing its additions with $ we are reserving our namespace
so that angular developers and developers who use Angular can develop in harmony without collisions.

View file

@ -0,0 +1,123 @@
@ngdoc overview
@name Filters
@description
A filter formats the value of an expression for display to the user. They can be used in view templates,
controllers or services and it is easy to define your own filter.
The underlying API is the {@link api/ng.$filterProvider filterProvider}.
## Using filters in view templates
Filters can be applied to expressions in view templates using the following syntax:
{{ expression | filter }}
E.g. the markup `{{ 12 | currency }}` formats the number 12 as a currency using the {@link api/ng.filter:currency `currency`}
filter. The resulting value is `$12.00`.
Filters can be applied to the result of another filter. This is called "chaining" and uses
the following syntax:
{{ expression | filter1 | filter2 | ... }}
Filters may have arguments. The syntax for this is
{{ expression | filter:argument1:argument2:... }}
E.g. the markup `{{ 1234 | number:2 }}` formats the number 1234 with 2 decimal points using the
{@link api/ng.filter:number `number`} filter. The resulting value is `1,234.00`.
## Using filters in controllers and services
You can also use filters in controllers and services. For this, add a dependency with the name `<filterName>Filter`
to your controller or service. E.g. using the dependency `numberFilter` will inject the number filter.
The injected argument is a function that takes the value to format as first argument and filter parameters
starting with the second argument.
The example below uses the filter called {@link api/ng.filter:filter `filter`}.
This filter reduces arrays into sub arrays based on
conditions. The filter can be applied in the view template with markup like
`{{ctrl.array | filter:'a'}}`, which would do a fulltext search for "a".
However, using a filter in a view template will reevaluate the filter on
every digest, which can be costly if the array is big.
The example below therefore calls the filter directly in the controller.
By this, the controller is able to call the filter only when needed (e.g. when the data is loaded from the backend
or the filter expression is changed).
<doc:example module="FilterInControllerModule">
<doc:source>
<script>
angular.module('FilterInControllerModule', []).
controller('FilterController', ['filterFilter', function(filterFilter) {
this.array = [
{name: 'Tobias'},
{name: 'Jeff'},
{name: 'Brian'},
{name: 'Igor'},
{name: 'James'},
{name: 'Brad'}
];
this.filteredArray = filterFilter(this.array, 'a');
}]);
</script>
<div ng-controller="FilterController as ctrl">
<div>
All entries:
<span ng-repeat="entry in ctrl.array">{{entry.name}} </span>
</div>
<div>
Entries that contain an "a":
<span ng-repeat="entry in ctrl.filteredArray">{{entry.name}} </span>
</div>
</div>
</doc:source>
</doc:example>
## Creating custom filters
Writing your own filter is very easy: just register a new filter factory function with
your module. Internally, this uses the {@link api/ng.$filterProvider `filterProvider`}.
This factory function should return a new filter function which takes the input value
as the first argument. Any filter arguments are passed in as additional arguments to the filter
function.
The following sample filter reverses a text string. In addition, it conditionally makes the
text upper-case.
<doc:example module="MyReverseModule">
<doc:source>
<script>
angular.module('MyReverseModule', []).
filter('reverse', function() {
return function(input, uppercase) {
var out = "";
for (var i = 0; i < input.length; i++) {
out = input.charAt(i) + out;
}
// conditional based on optional argument
if (uppercase) {
out = out.toUpperCase();
}
return out;
}
});
function Ctrl($scope) {
$scope.greeting = 'hello';
}
</script>
<div ng-controller="Ctrl">
<input ng-model="greeting" type="greeting"><br>
No filter: {{greeting}}<br>
Reverse: {{greeting|reverse}}<br>
Reverse + uppercase: {{greeting|reverse:true}}<br>
</div>
</doc:source>
</doc:example>

View file

@ -36,7 +36,7 @@ In Angular applications, you move the job of filling page templates with data fr
* {@link api/ngRoute.$route Views and routes (see the example)}
* {@link guide/dev_guide.templates.filters Filters}
* {@link guide/filter Filters}
* {@link guide/forms Forms} and [Concepts of AngularJS Forms](http://mrbool.com/the-concepts-of-angularjs-forms/29117)

View file

@ -1,5 +1,5 @@
@ngdoc overview
@name Angular Templates
@name Templates
@description
An Angular template is the declarative specification that, along with information from the model
@ -14,7 +14,7 @@ These are the types of Angular elements and element attributes you can use in a
augments an existing DOM element or represents a reusable DOM component - a widget.
* {@link api/ng.$interpolate Markup} — The double
curly brace notation `{{ }}` to bind expressions to elements is built-in angular markup.
* {@link dev_guide.templates.filters Filter} — Formats your data for display to the user.
* {@link filter Filter} — Formats your data for display to the user.
* {@link forms Form controls} — Lets you validate user input.
Note: In addition to declaring the elements above in templates, you can also access these elements
@ -49,7 +49,7 @@ eight.
## Related Topics
* {@link dev_guide.templates.filters Angular Filters}
* {@link filter Angular Filters}
* {@link forms Angular Forms}
## Related API

View file

@ -55,7 +55,7 @@ __`app/index.html`:__
</pre>
We added a standard HTML `<input>` tag and used Angular's
{@link api/ng.filter:filter $filter} function to process the input for the
{@link api/ng.filter:filter filter} function to process the input for the
{@link api/ng.directive:ngRepeat ngRepeat} directive.
This lets a user enter search criteria and immediately see the effects of their search on the phone

View file

@ -119,7 +119,7 @@ You should now see the following output in the Karma tab:
# Experiments
* Let's experiment with some of the {@link api/ng.$filter built-in Angular filters} and add the
* Let's experiment with some of the {@link api/ng.$filterProvider built-in Angular filters} and add the
following bindings to `index.html`:
* `{{ "lower cap string" | uppercase }}`
* `{{ {foo: "bar", baz: 23} | json }}`

View file

@ -677,9 +677,6 @@ function isLeafNode (node) {
* * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned.
* * If `source` is identical to 'destination' an exception will be thrown.
*
* Note: this function is used to augment the Object type in Angular expressions. See
* {@link ng.$filter} for more information about Angular arrays.
*
* @param {*} source The source that will be used to make a copy.
* Can be any type, including primitives, `null`, and `undefined`.
* @param {(Object|Array)=} destination Destination into which the source is copied. If

View file

@ -47,8 +47,7 @@
*
*
* For more information about how angular filters work, and how to create your own filters, see
* {@link guide/dev_guide.templates.filters Understanding Angular Filters} in the angular Developer
* Guide.
* {@link guide/filter Filters} in the Angular Developer Guide.
*/
/**
* @ngdoc method

View file

@ -8,9 +8,6 @@
* @description
* Selects a subset of items from `array` and returns it as a new array.
*
* Note: This function is used to augment the `Array` type in Angular expressions. See
* {@link ng.$filter} for more information about Angular arrays.
*
* @param {Array} array The source array.
* @param {string|Object|function()} expression The predicate to be used for selecting items from
* `array`.

View file

@ -10,9 +10,6 @@
* are taken from either the beginning or the end of the source array or string, as specified by
* the value and sign (positive or negative) of `limit`.
*
* Note: This function is used to augment the `Array` type in Angular expressions. See
* {@link ng.$filter} for more information about Angular arrays.
*
* @param {Array|string} input Source array or string to be limited.
* @param {string|number} limit The length of the returned array or string. If the `limit` number
* is positive, `limit` number of items from the beginning of the source array/string are copied.

View file

@ -8,9 +8,6 @@
* @description
* Orders a specified `array` by the `expression` predicate.
*
* Note: this function is used to augment the `Array` type in Angular expressions. See
* {@link ng.$filter} for more information about Angular arrays.
*
* @param {Array} array The array to sort.
* @param {function(*)|string|Array.<(function(*)|string)>} expression A predicate to be
* used by the comparator to determine the order of elements.