@@ -105,6 +105,26 @@ function $InterpolateProvider() {
105
105
* expect(exp({name:'Angular'}).toEqual('Hello ANGULAR!');
106
106
* ```
107
107
*
108
+ * `$interpolate` takes an optional fourth argument, `allOrNothing`. If `allOrNothing` is
109
+ * `true`, the interpolation function will return `undefined` unless all embedded expressions
110
+ * evaluate to a value other than `undefined`.
111
+ *
112
+ * ```js
113
+ * var $interpolate = ...; // injected
114
+ * var context = {greeting: 'Hey', name: undefined };
115
+ *
116
+ * // default "forgiving" mode
117
+ * var exp = $interpolate('{{greeting}} {{name}}!');
118
+ * expect(exp(context)).toEqual('Hello !');
119
+ *
120
+ * // "allOrNothing" mode
121
+ * exp = $interpolate('{{greeting}} {{name}}!', false, null, true);
122
+ * expect(exp(context, true)).toBeUndefined();
123
+ * context.name = 'Angular';
124
+ * expect(exp(context, true)).toEqual('Hello Angular!');
125
+ * ```
126
+ *
127
+ * `allOrNothing` is useful for interpolating URLs. `ngSrc` and `ngSrcset` use this behavior.
108
128
*
109
129
* @param {string } text The text with markup to interpolate.
110
130
* @param {boolean= } mustHaveExpression if set to true then the interpolation string must have
@@ -114,12 +134,15 @@ function $InterpolateProvider() {
114
134
* result through {@link ng.$sce#getTrusted $sce.getTrusted(interpolatedResult,
115
135
* trustedContext)} before returning it. Refer to the {@link ng.$sce $sce} service that
116
136
* provides Strict Contextual Escaping for details.
137
+ * @param {boolean= } allOrNothing if `true`, then the returned function returns undefined
138
+ * unless all embedded expressions evaluate to a value other than `undefined`.
117
139
* @returns {function(context) } an interpolation function which is used to compute the
118
140
* interpolated string. The function has these parameters:
119
141
*
120
142
* - `context`: evaluation context for all expressions embedded in the interpolated text
121
143
*/
122
- function $interpolate ( text , mustHaveExpression , trustedContext ) {
144
+ function $interpolate ( text , mustHaveExpression , trustedContext , allOrNothing ) {
145
+ allOrNothing = ! ! allOrNothing ;
123
146
var startIndex ,
124
147
endIndex ,
125
148
index = 0 ,
@@ -182,16 +205,21 @@ function $InterpolateProvider() {
182
205
return concat . join ( '' ) ;
183
206
} ;
184
207
185
- var stringify = function ( value ) {
208
+ var getValue = function ( value ) {
186
209
if ( trustedContext ) {
187
210
value = $sce . getTrusted ( trustedContext , value ) ;
188
211
} else {
189
212
value = $sce . valueOf ( value ) ;
190
213
}
191
214
192
- if ( value === null || isUndefined ( value ) ) {
215
+ return value ;
216
+ } ;
217
+
218
+ var stringify = function ( value ) {
219
+ if ( isUndefined ( value ) || value === null ) {
193
220
value = '' ;
194
- } else if ( typeof value != 'string' ) {
221
+ }
222
+ if ( typeof value != 'string' ) {
195
223
value = toJson ( value ) ;
196
224
}
197
225
@@ -225,7 +253,11 @@ function $InterpolateProvider() {
225
253
226
254
try {
227
255
for ( ; i < ii ; i ++ ) {
228
- val = stringify ( parseFns [ i ] ( context ) ) ;
256
+ val = getValue ( parseFns [ i ] ( context ) ) ;
257
+ if ( allOrNothing && isUndefined ( val ) ) {
258
+ return ;
259
+ }
260
+ val = stringify ( val ) ;
229
261
if ( val !== lastValues [ i ] ) {
230
262
inputsChanged = true ;
231
263
}
0 commit comments