|
303 | 303 | * name. Given `<my-component my-attr="parentModel">` and the isolate scope definition `scope: {
|
304 | 304 | * localModel: '=myAttr' }`, the property `localModel` on the directive's scope will reflect the
|
305 | 305 | * value of `parentModel` on the parent scope. Changes to `parentModel` will be reflected in
|
306 |
| - * `localModel` and vice versa. Optional attributes should be marked as such with a question mark: |
307 |
| - * `=?` or `=?attr`. If the binding expression is non-assignable, or if the attribute isn't |
308 |
| - * optional and doesn't exist, an exception ({@link error/$compile/nonassign `$compile:nonassign`}) |
309 |
| - * will be thrown upon discovering changes to the local value, since it will be impossible to sync |
310 |
| - * them back to the parent scope. By default, the {@link ng.$rootScope.Scope#$watch `$watch`} |
| 306 | + * `localModel` and vice versa. If the binding expression is non-assignable, or if the attribute |
| 307 | + * isn't optional and doesn't exist, an exception |
| 308 | + * ({@link error/$compile/nonassign `$compile:nonassign`}) will be thrown upon discovering changes |
| 309 | + * to the local value, since it will be impossible to sync them back to the parent scope. |
| 310 | + * |
| 311 | + * By default, the {@link ng.$rootScope.Scope#$watch `$watch`} |
311 | 312 | * method is used for tracking changes, and the equality check is based on object identity.
|
312 | 313 | * However, if an object literal or an array literal is passed as the binding expression, the
|
313 | 314 | * equality check is done by value (using the {@link angular.equals} function). It's also possible
|
314 | 315 | * to watch the evaluated value shallowly with {@link ng.$rootScope.Scope#$watchCollection
|
315 |
| - * `$watchCollection`}: use `=*` or `=*attr` (`=*?` or `=*?attr` if the attribute is optional). |
| 316 | + * `$watchCollection`}: use `=*` or `=*attr` |
316 | 317 | *
|
317 | 318 | * * `<` or `<attr` - set up a one-way (one-directional) binding between a local scope property and an
|
318 | 319 | * expression passed via the attribute `attr`. The expression is evaluated in the context of the
|
319 | 320 | * parent scope. If no `attr` name is specified then the attribute name is assumed to be the same as the
|
320 |
| - * local name. You can also make the binding optional by adding `?`: `<?` or `<?attr`. |
| 321 | + * local name. |
321 | 322 | *
|
322 | 323 | * For example, given `<my-component my-attr="parentModel">` and directive definition of
|
323 | 324 | * `scope: { localModel:'<myAttr' }`, then the isolated scope property `localModel` will reflect the
|
|
347 | 348 | * and values into the expression wrapper fn. For example, if the expression is `increment(amount)`
|
348 | 349 | * then we can specify the amount value by calling the `localFn` as `localFn({amount: 22})`.
|
349 | 350 | *
|
| 351 | + * All 4 kinds of bindings (`@`, `=`, `<`, and `&`) can be made optional by adding `?` to the expression. |
| 352 | + * The marker must come after the mode and before the attribute name. |
| 353 | + * See the {@link error/$compile/iscp Invalid Isolate Scope Definition error} for definition examples. |
| 354 | + * This is useful to refine the interface directives provide. |
| 355 | + * One subtle difference between optional and non-optional happens **when the binding attribute is not |
| 356 | + * set**: |
| 357 | + * - the binding is optional: the property will not be defined |
| 358 | + * - the binding is not optional: the property is defined |
| 359 | + * |
| 360 | + * ```js |
| 361 | + *app.directive('testDir', function() { |
| 362 | + return { |
| 363 | + scope: { |
| 364 | + notoptional: '=', |
| 365 | + optional: '=?', |
| 366 | + }, |
| 367 | + bindToController: true, |
| 368 | + controller: function() { |
| 369 | + this.$onInit = function() { |
| 370 | + console.log(this.hasOwnProperty('notoptional')) // true |
| 371 | + console.log(this.hasOwnProperty('optional')) // false |
| 372 | + } |
| 373 | + } |
| 374 | + } |
| 375 | + }) |
| 376 | + *``` |
| 377 | + * |
| 378 | + * |
| 379 | + * ##### Combining directives with different scope defintions |
| 380 | + * |
350 | 381 | * In general it's possible to apply more than one directive to one element, but there might be limitations
|
351 | 382 | * depending on the type of scope required by the directives. The following points will help explain these limitations.
|
352 | 383 | * For simplicity only two directives are taken into account, but it is also applicable for several directives:
|
|
0 commit comments