Skip to content

Commit 6bc2fac

Browse files
committed
feat($interpolate): add strict param to returned fn
1 parent fcc3a7a commit 6bc2fac

File tree

2 files changed

+42
-6
lines changed

2 files changed

+42
-6
lines changed

src/ng/interpolate.js

+37-6
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,26 @@ function $InterpolateProvider() {
105105
* expect(exp({name:'Angular'}).toEqual('Hello ANGULAR!');
106106
* ```
107107
*
108+
* The function returned by `$interpolate` takes an optional second argument, `allOrNothing`.
109+
* If `allOrNothing` is `true`, the interpolation function will return `undefined` unless all
110+
* embedded expressions within the text are defined.
111+
*
112+
* ```js
113+
* var $interpolate = ...; // injected
114+
* var exp = $interpolate('{{greeting}} {{name}}!');
115+
* var context = {greeting: 'Hey', name: undefined };
116+
*
117+
* // default "forgiving" mode
118+
* expect(exp(context).toEqual('Hello !');
119+
*
120+
* // "allOrNothing" mode
121+
* expect(exp(context, true).toBeUndefined();
122+
* context.name = 'Angular';
123+
* expect(exp(context, true).toEqual('Hello Angular!');
124+
* ```
125+
*
126+
* `allOrNothing` is useful for interpolating URLs. `ngHref`, `ngSrc`, and `ngSrcset` use this
127+
* behavior.
108128
*
109129
* @param {string} text The text with markup to interpolate.
110130
* @param {boolean=} mustHaveExpression if set to true then the interpolation string must have
@@ -114,10 +134,11 @@ function $InterpolateProvider() {
114134
* result through {@link ng.$sce#getTrusted $sce.getTrusted(interpolatedResult,
115135
* trustedContext)} before returning it. Refer to the {@link ng.$sce $sce} service that
116136
* provides Strict Contextual Escaping for details.
117-
* @returns {function(context)} an interpolation function which is used to compute the
137+
* @returns {function(context, allOrNothing)} an interpolation function which is used to compute the
118138
* interpolated string. The function has these parameters:
119139
*
120140
* - `context`: evaluation context for all expressions embedded in the interpolated text
141+
* - `allOrNothing`: if `true`, the undefined unless all embedded expressions are defined
121142
*/
122143
function $interpolate(text, mustHaveExpression, trustedContext) {
123144
var startIndex,
@@ -182,23 +203,29 @@ function $InterpolateProvider() {
182203
return concat.join('');
183204
};
184205

185-
var stringify = function (value) {
206+
var getValue = function (value) {
186207
if (trustedContext) {
187208
value = $sce.getTrusted(trustedContext, value);
188209
} else {
189210
value = $sce.valueOf(value);
190211
}
191212

192-
if (value === null || isUndefined(value)) {
213+
return value;
214+
};
215+
216+
var stringify = function (value) {
217+
if (isUndefined(value) || value === null) {
193218
value = '';
194-
} else if (typeof value != 'string') {
219+
}
220+
if (typeof value != 'string') {
195221
value = toJson(value);
196222
}
197223

198224
return value;
199225
};
200226

201-
return extend(function interpolationFn(context) {
227+
return extend(function interpolationFn(context, allOrNothing) {
228+
allOrNothing = !!allOrNothing;
202229
var scopeId = context.$id || 'notAScope';
203230
var lastValues = lastValuesCache.values[scopeId];
204231
var lastResult = lastValuesCache.results[scopeId];
@@ -225,7 +252,11 @@ function $InterpolateProvider() {
225252

226253
try {
227254
for (; i < ii; i++) {
228-
val = stringify(parseFns[i](context));
255+
val = getValue(parseFns[i](context));
256+
if (allOrNothing && isUndefined(val)) {
257+
return;
258+
}
259+
val = stringify(val);
229260
if (val !== lastValues[i]) {
230261
inputsChanged = true;
231262
}

test/ng/interpolateSpec.js

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ describe('$interpolate', function() {
1919
expect($interpolate('some text', true)).toBeUndefined();
2020
}));
2121

22+
it('should return undefined when there are bindings and strict is set to true',
23+
inject(function($interpolate) {
24+
expect($interpolate('test {{foo}}')({}, true)).toBeUndefined();
25+
}));
26+
2227
it('should suppress falsy objects', inject(function($interpolate) {
2328
expect($interpolate('{{undefined}}')({})).toEqual('');
2429
expect($interpolate('{{null}}')({})).toEqual('');

0 commit comments

Comments
 (0)