mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-05-17 11:11:05 +00:00
docs(guide/directive): split long lines
This commit is contained in:
parent
f6fa7c9c95
commit
089bf5f0e3
1 changed files with 84 additions and 67 deletions
|
|
@ -94,14 +94,16 @@ Here are some equivalent examples of elements that match `ngBind`:
|
||||||
|
|
||||||
<div class="alert alert-success">
|
<div class="alert alert-success">
|
||||||
**Best Practice:** Prefer using the dash-delimited format (e.g. `ng-bind` for `ngBind`).
|
**Best Practice:** Prefer using the dash-delimited format (e.g. `ng-bind` for `ngBind`).
|
||||||
If you want to use an HTML validating tool, you can instead use the `data`-prefixed version (e.g. `data-ng-bind` for `ngBind`).
|
If you want to use an HTML validating tool, you can instead use the `data`-prefixed version (e.g.
|
||||||
|
`data-ng-bind` for `ngBind`).
|
||||||
The other forms shown above are accepted for legacy reasons but we advise you to avoid them.
|
The other forms shown above are accepted for legacy reasons but we advise you to avoid them.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
`$compile` can match directives based on element names, attributes, class names, as well as comments.
|
`$compile` can match directives based on element names, attributes, class names, as well as comments.
|
||||||
|
|
||||||
All of the Angular-provided directives match attribute name, tag name, comments, or class name.
|
All of the Angular-provided directives match attribute name, tag name, comments, or class name.
|
||||||
The following demonstrates the various ways a directive (`myDir` in this case) can be referenced from within a template:
|
The following demonstrates the various ways a directive (`myDir` in this case) can be referenced
|
||||||
|
from within a template:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<my-dir></my-dir>
|
<my-dir></my-dir>
|
||||||
|
|
@ -127,10 +129,11 @@ directives when possible.
|
||||||
|
|
||||||
### Text and attribute bindings
|
### Text and attribute bindings
|
||||||
|
|
||||||
During the compilation process the {@link api/ng.$compile compiler} matches text and attributes using the
|
During the compilation process the {@link api/ng.$compile compiler} matches text and attributes
|
||||||
{@link api/ng.$interpolate $interpolate} service to see if they contain embedded expressions. These expressions
|
using the {@link api/ng.$interpolate $interpolate} service to see if they contain embedded
|
||||||
are registered as {@link api/ng.$rootScope.Scope#methods_$watch watches} and will update as part of normal {@link
|
expressions. These expressions are registered as {@link api/ng.$rootScope.Scope#methods_$watch watches}
|
||||||
api/ng.$rootScope.Scope#methods_$digest digest} cycle. An example of interpolation is shown below:
|
and will update as part of normal {@link api/ng.$rootScope.Scope#methods_$digest digest} cycle. An
|
||||||
|
example of interpolation is shown below:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<a ng-href="img/{{username}}.jpg">Hello {{username}}!</a>
|
<a ng-href="img/{{username}}.jpg">Hello {{username}}!</a>
|
||||||
|
|
@ -150,8 +153,8 @@ For example, considering this template:
|
||||||
```
|
```
|
||||||
|
|
||||||
We would expect Angular to be able to bind to this, but when we check the console we see
|
We would expect Angular to be able to bind to this, but when we check the console we see
|
||||||
something like `Error: Invalid value for attribute cx="{{cx}}"`. Because of the SVG DOM API's restrictions,
|
something like `Error: Invalid value for attribute cx="{{cx}}"`. Because of the SVG DOM API's
|
||||||
you cannot simply write `cx="{{cx}}"`.
|
restrictions, you cannot simply write `cx="{{cx}}"`.
|
||||||
|
|
||||||
With `ng-attr-cx` you can work around this problem.
|
With `ng-attr-cx` you can work around this problem.
|
||||||
|
|
||||||
|
|
@ -171,18 +174,19 @@ For example, we could fix the example above by instead writing:
|
||||||
|
|
||||||
## Creating Directives
|
## Creating Directives
|
||||||
|
|
||||||
First let's talk about the API for registering directives. Much like controllers, directives are registered on
|
First let's talk about the API for registering directives. Much like controllers, directives are
|
||||||
modules. To register a directive, you use the `module.directive` API. `module.directive` takes the
|
registered on modules. To register a directive, you use the `module.directive` API.
|
||||||
{@link guide/directive#creating-custom-directives_matching-directives normalized} directive name followed
|
`module.directive` takes the
|
||||||
by a **factory function.** This factory function should return
|
{@link guide/directive#creating-custom-directives_matching-directives normalized} directive name
|
||||||
an object with the different options to tell `$compile` how the directive should behave when matched.
|
followed by a **factory function.** This factory function should return an object with the different
|
||||||
|
options to tell `$compile` how the directive should behave when matched.
|
||||||
|
|
||||||
|
|
||||||
The factory function is invoked only once when the
|
The factory function is invoked only once when the
|
||||||
{@link api/ng.$compile compiler} matches the directive for the first time. You can
|
{@link api/ng.$compile compiler} matches the directive for the first time. You can perform any
|
||||||
perform any initialization work here. The function is invoked using {@link
|
initialization work here. The function is invoked using
|
||||||
api/AUTO.$injector#methods_invoke $injector.invoke} which
|
{@link api/AUTO.$injector#methods_invoke $injector.invoke} which makes it injectable just like a
|
||||||
makes it injectable just like a controller.
|
controller.
|
||||||
|
|
||||||
<div class="alert alert-success">
|
<div class="alert alert-success">
|
||||||
**Best Practice:** Prefer using the definition object over returning a function.
|
**Best Practice:** Prefer using the definition object over returning a function.
|
||||||
|
|
@ -205,9 +209,9 @@ For the following examples, we'll use the prefix `my` (e.g. `myCustomer`).
|
||||||
|
|
||||||
### Template-expanding directive
|
### Template-expanding directive
|
||||||
|
|
||||||
Let's say you have a chunk of your template that represents a customer's information. This template is repeated
|
Let's say you have a chunk of your template that represents a customer's information. This template
|
||||||
many times in your code. When you change it in one place, you have to change it in several others. This is a
|
is repeated many times in your code. When you change it in one place, you have to change it in
|
||||||
good opportunity to use a directive to simplify your template.
|
several others. This is a good opportunity to use a directive to simplify your template.
|
||||||
|
|
||||||
Let's create a directive that simply replaces its contents with a static template:
|
Let's create a directive that simply replaces its contents with a static template:
|
||||||
|
|
||||||
|
|
@ -233,21 +237,22 @@ Let's create a directive that simply replaces its contents with a static templat
|
||||||
</file>
|
</file>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
Notice that we have bindings in this directive. After `$compile` compiles and links `<div my-customer></div>`,
|
Notice that we have bindings in this directive. After `$compile` compiles and links
|
||||||
it will try to match directives on the element's children. This means you can compose directives of other directives.
|
`<div my-customer></div>`, it will try to match directives on the element's children. This means you
|
||||||
We'll see how to do that in {@link
|
can compose directives of other directives. We'll see how to do that in
|
||||||
guide/directive#creating-custom-directives_demo_creating-directives-that-communicate an example} below.
|
{@link guide/directive#creating-custom-directives_demo_creating-directives-that-communicate an example}
|
||||||
|
below.
|
||||||
|
|
||||||
In the example above we in-lined the value of the `template` option, but this will become annoying as the size
|
In the example above we in-lined the value of the `template` option, but this will become annoying
|
||||||
of your template grows.
|
as the size of your template grows.
|
||||||
|
|
||||||
<div class="alert alert-success">
|
<div class="alert alert-success">
|
||||||
**Best Practice:** Unless your template is very small, it's typically better to break it apart into its own
|
**Best Practice:** Unless your template is very small, it's typically better to break it apart into
|
||||||
HTML file and load it with the `templateUrl` option.
|
its own HTML file and load it with the `templateUrl` option.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
If you are familiar with `ngInclude`, `templateUrl` works just like it. Here's the same example using `templateUrl`
|
If you are familiar with `ngInclude`, `templateUrl` works just like it. Here's the same example
|
||||||
instead:
|
using `templateUrl` instead:
|
||||||
|
|
||||||
<example module="docsTemplateUrlDirective">
|
<example module="docsTemplateUrlDirective">
|
||||||
<file name="script.js">
|
<file name="script.js">
|
||||||
|
|
@ -278,8 +283,8 @@ Great! But what if we wanted to have our directive match the tag name `<my-custo
|
||||||
If we simply put a `<my-customer>` element into the HMTL, it doesn't work.
|
If we simply put a `<my-customer>` element into the HMTL, it doesn't work.
|
||||||
|
|
||||||
<div class="alert alert-waring">
|
<div class="alert alert-waring">
|
||||||
**Note:** When you create a directive, it is restricted to attribute only by default. In order to create
|
**Note:** When you create a directive, it is restricted to attribute only by default. In order to
|
||||||
directives that are triggered by element name, you need to use the `restrict` option.
|
create directives that are triggered by element name, you need to use the `restrict` option.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
The `restrict` option is typically set to:
|
The `restrict` option is typically set to:
|
||||||
|
|
@ -318,28 +323,33 @@ Let's change our directive to use `restrict: 'E'`:
|
||||||
</file>
|
</file>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
For more on the {@link api/ng.$compile#description_comprehensive-directive-api_directive-definition-object
|
For more on the
|
||||||
`restrict`, see the API docs}.
|
{@link api/ng.$compile#description_comprehensive-directive-api_directive-definition-object `restrict`}
|
||||||
|
property, see the
|
||||||
|
{@link api/ng.$compile#description_comprehensive-directive-api_directive-definition-object API docs}.
|
||||||
|
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
**When should I use an attribute versus an element?**
|
**When should I use an attribute versus an element?**
|
||||||
|
|
||||||
Use an element when you are creating a component that is in control of the template. The common case for this
|
Use an element when you are creating a component that is in control of the template. The common case
|
||||||
is when you are creating a Domain-Specific Language for parts of your template.
|
for this is when you are creating a Domain-Specific Language for parts of your template.
|
||||||
|
|
||||||
Use an attribute when you are decorating an existing element with new functionality.
|
Use an attribute when you are decorating an existing element with new functionality.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Using an element for the `myCustomer` directive is clearly the right choice because you're not decorating an element
|
Using an element for the `myCustomer` directive is clearly the right choice because you're not
|
||||||
with some "customer" behavior; you're defining the core behavior of the element as a customer component.
|
decorating an element with some "customer" behavior; you're defining the core behavior of the
|
||||||
|
element as a customer component.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Isolating the Scope of a Directive
|
### Isolating the Scope of a Directive
|
||||||
|
|
||||||
Our `myCustomer` directive above is great, but it has a fatal flaw. We can only use it once within a given scope.
|
Our `myCustomer` directive above is great, but it has a fatal flaw. We can only use it once within a
|
||||||
|
given scope.
|
||||||
|
|
||||||
In its current implementation, we'd need to create a different controller each time In order to re-use such a directive:
|
In its current implementation, we'd need to create a different controller each time In order to
|
||||||
|
re-use such a directive:
|
||||||
|
|
||||||
<example module="docsScopeProblemExample">
|
<example module="docsScopeProblemExample">
|
||||||
<file name="script.js">
|
<file name="script.js">
|
||||||
|
|
@ -380,8 +390,8 @@ In its current implementation, we'd need to create a different controller each t
|
||||||
This is clearly not a great solution.
|
This is clearly not a great solution.
|
||||||
|
|
||||||
What we want to be able to do is separate the scope inside a directive from the scope
|
What we want to be able to do is separate the scope inside a directive from the scope
|
||||||
outside, and then map the outer scope to a directive's inner scope. We can do this by creating what we call an
|
outside, and then map the outer scope to a directive's inner scope. We can do this by creating what
|
||||||
**isolate scope**. To do this, we can use a directive's `scope` option:
|
we call an **isolate scope**. To do this, we can use a directive's `scope` option:
|
||||||
|
|
||||||
<example module="docsIsolateScopeDirective">
|
<example module="docsIsolateScopeDirective">
|
||||||
<file name="script.js">
|
<file name="script.js">
|
||||||
|
|
@ -412,8 +422,8 @@ outside, and then map the outer scope to a directive's inner scope. We can do th
|
||||||
</file>
|
</file>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
Looking at `index.html`, the first `<my-customer>` element binds the inner scope's `customer` to `naomi`,
|
Looking at `index.html`, the first `<my-customer>` element binds the inner scope's `customer` to
|
||||||
which we have exposed on our controller's scope. The second binds `customer` to `igor`.
|
`naomi`, which we have exposed on our controller's scope. The second binds `customer` to `igor`.
|
||||||
|
|
||||||
Let's take a closer look at the scope option:
|
Let's take a closer look at the scope option:
|
||||||
|
|
||||||
|
|
@ -425,16 +435,18 @@ scope: {
|
||||||
//...
|
//...
|
||||||
```
|
```
|
||||||
|
|
||||||
The property name (`customer`) corresponds to the variable name of the `myCustomer` directive's isolated scope.
|
The property name (`customer`) corresponds to the variable name of the `myCustomer` directive's
|
||||||
The value of the property (`=customer`) tells `$compile` to bind to the `customer` attribute.
|
isolated scope. The value of the property (`=customer`) tells `$compile` to bind to the `customer`
|
||||||
|
attribute.
|
||||||
|
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
**Note:** These `=attr` attributes in the `scope` option of directives are normalized just like directive names.
|
**Note:** These `=attr` attributes in the `scope` option of directives are normalized just like
|
||||||
To bind to the attribute in `<div bind-to-this="thing">`, you'd specify a binding of `=bindToThis`.
|
directive names. To bind to the attribute in `<div bind-to-this="thing">`, you'd specify a binding
|
||||||
|
of `=bindToThis`.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
For cases where the attribute name is the same as the value you want to bind to inside
|
For cases where the attribute name is the same as the value you want to bind to inside the
|
||||||
the directive's scope, you can use this shorthand syntax:
|
directive's scope, you can use this shorthand syntax:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
//...
|
//...
|
||||||
|
|
@ -445,11 +457,11 @@ scope: {
|
||||||
//...
|
//...
|
||||||
```
|
```
|
||||||
|
|
||||||
Besides making it possible to bind different data to the scope inside a directive, using an isolated scope has another
|
Besides making it possible to bind different data to the scope inside a directive, using an isolated
|
||||||
effect.
|
scope has another effect.
|
||||||
|
|
||||||
We can show this by adding another property, `vojta`, to our scope and trying to access it
|
We can show this by adding another property, `vojta`, to our scope and trying to access it from
|
||||||
from within our directive's template:
|
within our directive's template:
|
||||||
|
|
||||||
<example module="docsIsolationExample">
|
<example module="docsIsolationExample">
|
||||||
<file name="script.js">
|
<file name="script.js">
|
||||||
|
|
@ -505,7 +517,8 @@ In this example we will build a directive that displays the current time.
|
||||||
Once a second, it updates the DOM to reflect the current time.
|
Once a second, it updates the DOM to reflect the current time.
|
||||||
|
|
||||||
Directives that want to modify the DOM typically use the `link` option.
|
Directives that want to modify the DOM typically use the `link` option.
|
||||||
`link` takes a function with the following signature, `function link(scope, element, attrs) { ... }` where:
|
`link` takes a function with the following signature, `function link(scope, element, attrs) { ... }`
|
||||||
|
where:
|
||||||
|
|
||||||
* `scope` is an Angular scope object.
|
* `scope` is an Angular scope object.
|
||||||
* `element` is the jqLite-wrapped element that this directive matches.
|
* `element` is the jqLite-wrapped element that this directive matches.
|
||||||
|
|
@ -566,8 +579,9 @@ if the directive is deleted so we don't introduce a memory leak.
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
There are a couple of things to note here.
|
There are a couple of things to note here.
|
||||||
Just like the `module.controller` API, the function argument in `module.directive` is dependency injected.
|
Just like the `module.controller` API, the function argument in `module.directive` is dependency
|
||||||
Because of this, we can use `$timeout` and `dateFilter` inside our directive's `link` function.
|
injected. Because of this, we can use `$timeout` and `dateFilter` inside our directive's `link`
|
||||||
|
function.
|
||||||
|
|
||||||
We register an event `element.on('$destroy', ...)`. What fires this `$destroy` event?
|
We register an event `element.on('$destroy', ...)`. What fires this `$destroy` event?
|
||||||
|
|
||||||
|
|
@ -581,8 +595,9 @@ but if you registered a listener on a service, or registered a listener on a DOM
|
||||||
being deleted, you'll have to clean it up yourself or you risk introducing a memory leak.
|
being deleted, you'll have to clean it up yourself or you risk introducing a memory leak.
|
||||||
|
|
||||||
<div class="alert alert-success">
|
<div class="alert alert-success">
|
||||||
**Best Practice:** Directives should clean up after themselves. You can use `element.on('$destroy', ...)`
|
**Best Practice:** Directives should clean up after themselves. You can use
|
||||||
or `scope.$on('$destroy', ...)` to run a clean-up function when the directive is removed.
|
`element.on('$destroy', ...)` or `scope.$on('$destroy', ...)` to run a clean-up function when the
|
||||||
|
directive is removed.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -620,11 +635,11 @@ To do this, we need to use the `transclude` option.
|
||||||
</file>
|
</file>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
What does this `transclude` option do, exactly? `transclude` makes the contents of a directive with this
|
What does this `transclude` option do, exactly? `transclude` makes the contents of a directive with
|
||||||
option have access to the scope **outside** of the directive rather than inside.
|
this option have access to the scope **outside** of the directive rather than inside.
|
||||||
|
|
||||||
To illustrate this, see the example below. Notice that we've added a `link` function in `script.js` that
|
To illustrate this, see the example below. Notice that we've added a `link` function in `script.js`
|
||||||
redefines `name` as `Jeff`. What do you think the `{{name}}` binding will resolve to now?
|
that redefines `name` as `Jeff`. What do you think the `{{name}}` binding will resolve to now?
|
||||||
|
|
||||||
<example module="docsTransclusionExample">
|
<example module="docsTransclusionExample">
|
||||||
<file name="script.js">
|
<file name="script.js">
|
||||||
|
|
@ -670,11 +685,12 @@ pass in each model you wanted to use separately. If you have to pass in each mod
|
||||||
use, then you can't really have arbitrary contents, can you?
|
use, then you can't really have arbitrary contents, can you?
|
||||||
|
|
||||||
<div class="alert alert-success">
|
<div class="alert alert-success">
|
||||||
**Best Practice:** only use `transclude: true` when you want to create a directive that wraps arbitrary content.
|
**Best Practice:** only use `transclude: true` when you want to create a directive that wraps
|
||||||
|
arbitrary content.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Next, we want to add buttons to this dialog box, and allow someone using the directive to bind their own
|
Next, we want to add buttons to this dialog box, and allow someone using the directive to bind their
|
||||||
behavior to it.
|
own behavior to it.
|
||||||
|
|
||||||
<example module="docsIsoFnBindExample">
|
<example module="docsIsoFnBindExample">
|
||||||
<file name="script.js">
|
<file name="script.js">
|
||||||
|
|
@ -894,5 +910,6 @@ point for creating your own directives.
|
||||||
You might also be interested in an in-depth explanation of the compilation process that's
|
You might also be interested in an in-depth explanation of the compilation process that's
|
||||||
available in the {@link guide/compiler compiler guide}.
|
available in the {@link guide/compiler compiler guide}.
|
||||||
|
|
||||||
The {@link api/ng.$compile `$compile` API} page has a comprehensive list of directive options for reference.
|
The {@link api/ng.$compile `$compile` API} page has a comprehensive list of directive options for
|
||||||
|
reference.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue