@@ -94,14 +94,16 @@ Here are some equivalent examples of elements that match `ngBind`:
94
94
95
95
<div class="alert alert-success">
96
96
**Best Practice:** Prefer using the dash-delimited format (e.g. `ng-bind` for `ngBind`).
97
- If you want to use an HTML validating tool, you can instead use the `data`-prefixed version (e.g. `data-ng-bind` for `ngBind`).
97
+ If you want to use an HTML validating tool, you can instead use the `data`-prefixed version (e.g.
98
+ `data-ng-bind` for `ngBind`).
98
99
The other forms shown above are accepted for legacy reasons but we advise you to avoid them.
99
100
</div>
100
101
101
102
`$compile` can match directives based on element names, attributes, class names, as well as comments.
102
103
103
104
All of the Angular-provided directives match attribute name, tag name, comments, or class name.
104
- The following demonstrates the various ways a directive (`myDir` in this case) can be referenced from within a template:
105
+ The following demonstrates the various ways a directive (`myDir` in this case) can be referenced
106
+ from within a template:
105
107
106
108
```html
107
109
<my-dir></my-dir>
@@ -127,10 +129,11 @@ directives when possible.
127
129
128
130
### Text and attribute bindings
129
131
130
- During the compilation process the {@link api/ng.$compile compiler} matches text and attributes using the
131
- {@link api/ng.$interpolate $interpolate} service to see if they contain embedded expressions. These expressions
132
- are registered as {@link api/ng.$rootScope.Scope#methods_$watch watches} and will update as part of normal {@link
133
- api/ng.$rootScope.Scope#methods_$digest digest} cycle. An example of interpolation is shown below:
132
+ During the compilation process the {@link api/ng.$compile compiler} matches text and attributes
133
+ using the {@link api/ng.$interpolate $interpolate} service to see if they contain embedded
134
+ expressions. These expressions are registered as {@link api/ng.$rootScope.Scope#methods_$watch watches}
135
+ and will update as part of normal {@link api/ng.$rootScope.Scope#methods_$digest digest} cycle. An
136
+ example of interpolation is shown below:
134
137
135
138
```html
136
139
<a ng-href="img/{{username}}.jpg">Hello {{username}}!</a>
@@ -150,8 +153,8 @@ For example, considering this template:
150
153
```
151
154
152
155
We would expect Angular to be able to bind to this, but when we check the console we see
153
- something like `Error: Invalid value for attribute cx="{{cx}}"`. Because of the SVG DOM API's restrictions,
154
- you cannot simply write `cx="{{cx}}"`.
156
+ something like `Error: Invalid value for attribute cx="{{cx}}"`. Because of the SVG DOM API's
157
+ restrictions, you cannot simply write `cx="{{cx}}"`.
155
158
156
159
With `ng-attr-cx` you can work around this problem.
157
160
@@ -171,18 +174,19 @@ For example, we could fix the example above by instead writing:
171
174
172
175
## Creating Directives
173
176
174
- First let's talk about the API for registering directives. Much like controllers, directives are registered on
175
- modules. To register a directive, you use the `module.directive` API. `module.directive` takes the
176
- {@link guide/directive#creating-custom-directives_matching-directives normalized} directive name followed
177
- by a **factory function.** This factory function should return
178
- an object with the different options to tell `$compile` how the directive should behave when matched.
177
+ First let's talk about the API for registering directives. Much like controllers, directives are
178
+ registered on modules. To register a directive, you use the `module.directive` API.
179
+ `module.directive` takes the
180
+ {@link guide/directive#creating-custom-directives_matching-directives normalized} directive name
181
+ followed by a **factory function.** This factory function should return an object with the different
182
+ options to tell `$compile` how the directive should behave when matched.
179
183
180
184
181
185
The factory function is invoked only once when the
182
- {@link api/ng.$compile compiler} matches the directive for the first time. You can
183
- perform any initialization work here. The function is invoked using {@link
184
- api/AUTO.$injector#methods_invoke $injector.invoke} which
185
- makes it injectable just like a controller.
186
+ {@link api/ng.$compile compiler} matches the directive for the first time. You can perform any
187
+ initialization work here. The function is invoked using
188
+ {@link api/AUTO.$injector#methods_invoke $injector.invoke} which makes it injectable just like a
189
+ controller.
186
190
187
191
<div class="alert alert-success">
188
192
**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`).
205
209
206
210
### Template-expanding directive
207
211
208
- Let's say you have a chunk of your template that represents a customer's information. This template is repeated
209
- many times in your code. When you change it in one place, you have to change it in several others. This is a
210
- good opportunity to use a directive to simplify your template.
212
+ Let's say you have a chunk of your template that represents a customer's information. This template
213
+ is repeated many times in your code. When you change it in one place, you have to change it in
214
+ several others. This is a good opportunity to use a directive to simplify your template.
211
215
212
216
Let's create a directive that simply replaces its contents with a static template:
213
217
@@ -233,21 +237,22 @@ Let's create a directive that simply replaces its contents with a static templat
233
237
</file>
234
238
</example>
235
239
236
- Notice that we have bindings in this directive. After `$compile` compiles and links `<div my-customer></div>`,
237
- it will try to match directives on the element's children. This means you can compose directives of other directives.
238
- We'll see how to do that in {@link
239
- guide/directive#creating-custom-directives_demo_creating-directives-that-communicate an example} below.
240
+ Notice that we have bindings in this directive. After `$compile` compiles and links
241
+ `<div my-customer></div>`, it will try to match directives on the element's children. This means you
242
+ can compose directives of other directives. We'll see how to do that in
243
+ {@link guide/directive#creating-custom-directives_demo_creating-directives-that-communicate an example}
244
+ below.
240
245
241
- In the example above we in-lined the value of the `template` option, but this will become annoying as the size
242
- of your template grows.
246
+ In the example above we in-lined the value of the `template` option, but this will become annoying
247
+ as the size of your template grows.
243
248
244
249
<div class="alert alert-success">
245
- **Best Practice:** Unless your template is very small, it's typically better to break it apart into its own
246
- HTML file and load it with the `templateUrl` option.
250
+ **Best Practice:** Unless your template is very small, it's typically better to break it apart into
251
+ its own HTML file and load it with the `templateUrl` option.
247
252
</div>
248
253
249
- If you are familiar with `ngInclude`, `templateUrl` works just like it. Here's the same example using `templateUrl`
250
- instead:
254
+ If you are familiar with `ngInclude`, `templateUrl` works just like it. Here's the same example
255
+ using `templateUrl` instead:
251
256
252
257
<example module="docsTemplateUrlDirective">
253
258
<file name="script.js">
@@ -278,8 +283,8 @@ Great! But what if we wanted to have our directive match the tag name `<my-custo
278
283
If we simply put a `<my-customer>` element into the HMTL, it doesn't work.
279
284
280
285
<div class="alert alert-waring">
281
- **Note:** When you create a directive, it is restricted to attribute only by default. In order to create
282
- directives that are triggered by element name, you need to use the `restrict` option.
286
+ **Note:** When you create a directive, it is restricted to attribute only by default. In order to
287
+ create directives that are triggered by element name, you need to use the `restrict` option.
283
288
</div>
284
289
285
290
The `restrict` option is typically set to:
@@ -318,28 +323,33 @@ Let's change our directive to use `restrict: 'E'`:
318
323
</file>
319
324
</example>
320
325
321
- For more on the {@link api/ng.$compile#description_comprehensive-directive-api_directive-definition-object
322
- `restrict`, see the API docs}.
326
+ For more on the
327
+ {@link api/ng.$compile#description_comprehensive-directive-api_directive-definition-object `restrict`}
328
+ property, see the
329
+ {@link api/ng.$compile#description_comprehensive-directive-api_directive-definition-object API docs}.
323
330
324
331
<div class="alert alert-info">
325
332
**When should I use an attribute versus an element?**
326
333
327
- Use an element when you are creating a component that is in control of the template. The common case for this
328
- is when you are creating a Domain-Specific Language for parts of your template.
334
+ Use an element when you are creating a component that is in control of the template. The common case
335
+ for this is when you are creating a Domain-Specific Language for parts of your template.
329
336
330
337
Use an attribute when you are decorating an existing element with new functionality.
331
338
</div>
332
339
333
- Using an element for the `myCustomer` directive is clearly the right choice because you're not decorating an element
334
- with some "customer" behavior; you're defining the core behavior of the element as a customer component.
340
+ Using an element for the `myCustomer` directive is clearly the right choice because you're not
341
+ decorating an element with some "customer" behavior; you're defining the core behavior of the
342
+ element as a customer component.
335
343
336
344
337
345
338
346
### Isolating the Scope of a Directive
339
347
340
- Our `myCustomer` directive above is great, but it has a fatal flaw. We can only use it once within a given scope.
348
+ Our `myCustomer` directive above is great, but it has a fatal flaw. We can only use it once within a
349
+ given scope.
341
350
342
- In its current implementation, we'd need to create a different controller each time In order to re-use such a directive:
351
+ In its current implementation, we'd need to create a different controller each time In order to
352
+ re-use such a directive:
343
353
344
354
<example module="docsScopeProblemExample">
345
355
<file name="script.js">
@@ -380,8 +390,8 @@ In its current implementation, we'd need to create a different controller each t
380
390
This is clearly not a great solution.
381
391
382
392
What we want to be able to do is separate the scope inside a directive from the scope
383
- outside, and then map the outer scope to a directive's inner scope. We can do this by creating what we call an
384
- **isolate scope**. To do this, we can use a directive's `scope` option:
393
+ outside, and then map the outer scope to a directive's inner scope. We can do this by creating what
394
+ we call an **isolate scope**. To do this, we can use a directive's `scope` option:
385
395
386
396
<example module="docsIsolateScopeDirective">
387
397
<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
412
422
</file>
413
423
</example>
414
424
415
- Looking at `index.html`, the first `<my-customer>` element binds the inner scope's `customer` to `naomi`,
416
- which we have exposed on our controller's scope. The second binds `customer` to `igor`.
425
+ Looking at `index.html`, the first `<my-customer>` element binds the inner scope's `customer` to
426
+ `naomi`, which we have exposed on our controller's scope. The second binds `customer` to `igor`.
417
427
418
428
Let's take a closer look at the scope option:
419
429
@@ -425,16 +435,18 @@ scope: {
425
435
//...
426
436
```
427
437
428
- The property name (`customer`) corresponds to the variable name of the `myCustomer` directive's isolated scope.
429
- The value of the property (`=customer`) tells `$compile` to bind to the `customer` attribute.
438
+ The property name (`customer`) corresponds to the variable name of the `myCustomer` directive's
439
+ isolated scope. The value of the property (`=customer`) tells `$compile` to bind to the `customer`
440
+ attribute.
430
441
431
442
<div class="alert alert-warning">
432
- **Note:** These `=attr` attributes in the `scope` option of directives are normalized just like directive names.
433
- To bind to the attribute in `<div bind-to-this="thing">`, you'd specify a binding of `=bindToThis`.
443
+ **Note:** These `=attr` attributes in the `scope` option of directives are normalized just like
444
+ directive names. To bind to the attribute in `<div bind-to-this="thing">`, you'd specify a binding
445
+ of `=bindToThis`.
434
446
</div>
435
447
436
- For cases where the attribute name is the same as the value you want to bind to inside
437
- the directive's scope, you can use this shorthand syntax:
448
+ For cases where the attribute name is the same as the value you want to bind to inside the
449
+ directive's scope, you can use this shorthand syntax:
438
450
439
451
```javascript
440
452
//...
@@ -445,11 +457,11 @@ scope: {
445
457
//...
446
458
```
447
459
448
- Besides making it possible to bind different data to the scope inside a directive, using an isolated scope has another
449
- effect.
460
+ Besides making it possible to bind different data to the scope inside a directive, using an isolated
461
+ scope has another effect.
450
462
451
- We can show this by adding another property, `vojta`, to our scope and trying to access it
452
- from within our directive's template:
463
+ We can show this by adding another property, `vojta`, to our scope and trying to access it from
464
+ within our directive's template:
453
465
454
466
<example module="docsIsolationExample">
455
467
<file name="script.js">
@@ -505,7 +517,8 @@ In this example we will build a directive that displays the current time.
505
517
Once a second, it updates the DOM to reflect the current time.
506
518
507
519
Directives that want to modify the DOM typically use the `link` option.
508
- `link` takes a function with the following signature, `function link(scope, element, attrs) { ... }` where:
520
+ `link` takes a function with the following signature, `function link(scope, element, attrs) { ... }`
521
+ where:
509
522
510
523
* `scope` is an Angular scope object.
511
524
* `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.
566
579
</example>
567
580
568
581
There are a couple of things to note here.
569
- Just like the `module.controller` API, the function argument in `module.directive` is dependency injected.
570
- Because of this, we can use `$timeout` and `dateFilter` inside our directive's `link` function.
582
+ Just like the `module.controller` API, the function argument in `module.directive` is dependency
583
+ injected. Because of this, we can use `$timeout` and `dateFilter` inside our directive's `link`
584
+ function.
571
585
572
586
We register an event `element.on('$destroy', ...)`. What fires this `$destroy` event?
573
587
@@ -581,8 +595,9 @@ but if you registered a listener on a service, or registered a listener on a DOM
581
595
being deleted, you'll have to clean it up yourself or you risk introducing a memory leak.
582
596
583
597
<div class="alert alert-success">
584
- **Best Practice:** Directives should clean up after themselves. You can use `element.on('$destroy', ...)`
585
- or `scope.$on('$destroy', ...)` to run a clean-up function when the directive is removed.
598
+ **Best Practice:** Directives should clean up after themselves. You can use
599
+ `element.on('$destroy', ...)` or `scope.$on('$destroy', ...)` to run a clean-up function when the
600
+ directive is removed.
586
601
</div>
587
602
588
603
@@ -620,11 +635,11 @@ To do this, we need to use the `transclude` option.
620
635
</file>
621
636
</example>
622
637
623
- What does this `transclude` option do, exactly? `transclude` makes the contents of a directive with this
624
- option have access to the scope **outside** of the directive rather than inside.
638
+ What does this `transclude` option do, exactly? `transclude` makes the contents of a directive with
639
+ this option have access to the scope **outside** of the directive rather than inside.
625
640
626
- To illustrate this, see the example below. Notice that we've added a `link` function in `script.js` that
627
- redefines `name` as `Jeff`. What do you think the `{{name}}` binding will resolve to now?
641
+ To illustrate this, see the example below. Notice that we've added a `link` function in `script.js`
642
+ that redefines `name` as `Jeff`. What do you think the `{{name}}` binding will resolve to now?
628
643
629
644
<example module="docsTransclusionExample">
630
645
<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
670
685
use, then you can't really have arbitrary contents, can you?
671
686
672
687
<div class="alert alert-success">
673
- **Best Practice:** only use `transclude: true` when you want to create a directive that wraps arbitrary content.
688
+ **Best Practice:** only use `transclude: true` when you want to create a directive that wraps
689
+ arbitrary content.
674
690
</div>
675
691
676
- Next, we want to add buttons to this dialog box, and allow someone using the directive to bind their own
677
- behavior to it.
692
+ Next, we want to add buttons to this dialog box, and allow someone using the directive to bind their
693
+ own behavior to it.
678
694
679
695
<example module="docsIsoFnBindExample">
680
696
<file name="script.js">
@@ -894,5 +910,6 @@ point for creating your own directives.
894
910
You might also be interested in an in-depth explanation of the compilation process that's
895
911
available in the {@link guide/compiler compiler guide}.
896
912
897
- The {@link api/ng.$compile `$compile` API} page has a comprehensive list of directive options for reference.
913
+ The {@link api/ng.$compile `$compile` API} page has a comprehensive list of directive options for
914
+ reference.
898
915
0 commit comments