Skip to content

Commit

Permalink
docs(guide/filter): Refactor filter guide docs
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tbosch authored and jamesdaily committed Jan 27, 2014
1 parent bdb82b0 commit 310e3c4
Show file tree
Hide file tree
Showing 18 changed files with 138 additions and 193 deletions.
2 changes: 1 addition & 1 deletion docs/content/api/index.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -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 `$$`.
Expand Down
8 changes: 4 additions & 4 deletions docs/content/guide/concepts.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down
2 changes: 1 addition & 1 deletion docs/content/guide/controller.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down

This file was deleted.

23 changes: 0 additions & 23 deletions docs/content/guide/dev_guide.templates.filters.ngdoc

This file was deleted.

44 changes: 0 additions & 44 deletions docs/content/guide/dev_guide.templates.filters.using_filters.ngdoc

This file was deleted.

2 changes: 1 addition & 1 deletion docs/content/guide/dev_guide.unit-testing.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
40 changes: 1 addition & 39 deletions docs/content/guide/expression.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -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`


Expand All @@ -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.
Expand Down Expand Up @@ -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.

123 changes: 123 additions & 0 deletions docs/content/guide/filter.ngdoc
Original file line number Diff line number Diff line change
@@ -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>

2 changes: 1 addition & 1 deletion docs/content/guide/index.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
Loading

0 comments on commit 310e3c4

Please sign in to comment.