186
186
* you want to shallow watch for changes (i.e. $watchCollection instead of $watch) you can use
187
187
* `=*` or `=*attr` (`=*?` or `=*?attr` if the property is optional).
188
188
*
189
+ * * `<` or `<attr` - set up one-way (one-directional) binding between a local scope property and the
190
+ * parent scope property of name defined via the value of the `attr` attribute. If no `attr`
191
+ * name is specified then the attribute name is assumed to be the same as the local name.
192
+ * Given `<dir my-attr="parentModel">` and directive definition of
193
+ * `scope: { localModel:'<myAttr' }`, then isolate scope property `localModel` will reflect the
194
+ * value of `parentModel` on the parent scope. Any changes to `parentModel` will be reflected
195
+ * in `localModel`, but changes in `localModel` will not reflect in `parentModel`. There are however
196
+ * two caveats:
197
+ * 1. one-way binding does not copy the value from the parent to the isolate scope, it simply
198
+ * sets the same value. That means if your bound value is an object, changes to its properties
199
+ * in the isolate scope will be reflected in the parent scope.
200
+ * 2. one-way binding watches changes to the **identity** of the parent value. That is important should
201
+ * you replace a bound object in the isolated scope. In that case, you must also replace your
202
+ * object in ther parent scope with a new one, otherwise the one-way binding won't pick up changes.
203
+ *
204
+ * One-way binding is useful if you do not plan to propagate changes to your isolated scope bindings
205
+ * back to the parent. It does not however not make this completely impossible.
206
+ *
207
+ * Same as with bi-directional bindings, you can also use shallow watch for changes (i.e. $watchCollection instead of $watch):
208
+ * `<*` or `<*attr` (`<*?` or `<*?attr` if the property is optional).
209
+ *
189
210
* * `&` or `&attr` - provides a way to execute an expression in the context of the parent scope.
190
211
* If no `attr` name is specified then the attribute name is assumed to be the same as the
191
212
* local name. Given `<widget my-attr="count = count + value">` and widget definition of
@@ -826,7 +847,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
826
847
var EVENT_HANDLER_ATTR_REGEXP = / ^ ( o n [ a - z ] + | f o r m a c t i o n ) $ / ;
827
848
828
849
function parseIsolateBindings ( scope , directiveName , isController ) {
829
- var LOCAL_REGEXP = / ^ \s * ( [ @ & ] | = ( \* ? ) ) ( \? ? ) \s * ( \w * ) \s * $ / ;
850
+ var LOCAL_REGEXP = / ^ \s * ( [ @ & ] | [ = < ] ( \* ? ) ) ( \? ? ) \s * ( \w * ) \s * $ / ;
830
851
831
852
var bindings = { } ;
832
853
@@ -2962,7 +2983,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
2962
2983
optional = definition . optional ,
2963
2984
mode = definition . mode , // @, =, or &
2964
2985
lastValue ,
2965
- parentGet , parentSet , compare ;
2986
+ parentGet , parentSet , compare , removeWatch ;
2966
2987
2967
2988
switch ( mode ) {
2968
2989
@@ -3023,7 +3044,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
3023
3044
return lastValue = parentValue ;
3024
3045
} ;
3025
3046
parentValueWatch . $stateful = true ;
3026
- var removeWatch ;
3027
3047
if ( definition . collection ) {
3028
3048
removeWatch = scope . $watchCollection ( attrs [ attrName ] , parentValueWatch ) ;
3029
3049
} else {
@@ -3032,6 +3052,29 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
3032
3052
removeWatchCollection . push ( removeWatch ) ;
3033
3053
break ;
3034
3054
3055
+ case '<' :
3056
+ if ( ! hasOwnProperty . call ( attrs , attrName ) ) {
3057
+ if ( optional ) break ;
3058
+ attrs [ attrName ] = void 0 ;
3059
+ }
3060
+ if ( optional && ! attrs [ attrName ] ) break ;
3061
+
3062
+ parentGet = $parse ( attrs [ attrName ] ) ;
3063
+
3064
+ destination [ scopeName ] = parentGet ( scope ) ;
3065
+
3066
+ function onParentValueChange ( newParentValue ) {
3067
+ destination [ scopeName ] = newParentValue ;
3068
+ }
3069
+
3070
+ if ( definition . collection ) {
3071
+ removeWatch = scope . $watchCollection ( $parse ( attrs [ attrName ] ) , onParentValueChange ) ;
3072
+ } else {
3073
+ removeWatch = scope . $watch ( $parse ( attrs [ attrName ] ) , onParentValueChange ) ;
3074
+ }
3075
+ removeWatchCollection . push ( removeWatch ) ;
3076
+ break ;
3077
+
3035
3078
case '&' :
3036
3079
// Don't assign Object.prototype method to scope
3037
3080
parentGet = attrs . hasOwnProperty ( attrName ) ? $parse ( attrs [ attrName ] ) : noop ;
0 commit comments