Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 05da211

Browse files
committed
fix(ngBind): use same json conversion as $interpolate
Fixes #11716 BREAKING CHANGE: `ngBind` now uses the same logic as $interpolate (i.e. {{myString}}) when binding, which means objects are now transformed with JSON.stringify. Before, it would use the object's toString() function. The following example shows the different output: ```js $scope.myObject = {a: 1, b: 2}; ``` ```html <span ng-bind="myObject"></span> ``` Before: ```html <span ng-bind="myObject">[object Object]</span> ``` After: ```html <span ng-bind="myObject">{"a":1,"b":2}</span> ```
1 parent cd3673e commit 05da211

File tree

5 files changed

+30
-18
lines changed

5 files changed

+30
-18
lines changed

src/.jshintrc

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
"createMap": false,
9797
"VALIDITY_STATE_PROPERTY": false,
9898
"reloadWithDebugInfo": false,
99+
"stringify": false,
99100

100101
"NODE_TYPE_ELEMENT": false,
101102
"NODE_TYPE_ATTRIBUTE": false,

src/Angular.js

+19
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
getBlockNodes: true,
8888
hasOwnProperty: true,
8989
createMap: true,
90+
stringify: true,
9091
9192
NODE_TYPE_ELEMENT: true,
9293
NODE_TYPE_ATTRIBUTE: true,
@@ -1929,6 +1930,24 @@ function createMap() {
19291930
return Object.create(null);
19301931
}
19311932

1933+
1934+
function stringify(value) {
1935+
if (value == null) { // null || undefined
1936+
return '';
1937+
}
1938+
switch (typeof value) {
1939+
case 'string':
1940+
break;
1941+
case 'number':
1942+
value = '' + value;
1943+
break;
1944+
default:
1945+
value = toJson(value);
1946+
}
1947+
1948+
return value;
1949+
}
1950+
19321951
var NODE_TYPE_ELEMENT = 1;
19331952
var NODE_TYPE_ATTRIBUTE = 2;
19341953
var NODE_TYPE_TEXT = 3;

src/ng/directive/ngBind.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ var ngBindDirective = ['$compile', function($compile) {
6060
$compile.$$addBindingInfo(element, attr.ngBind);
6161
element = element[0];
6262
scope.$watch(attr.ngBind, function ngBindWatchAction(value) {
63-
element.textContent = isUndefined(value) ? '' : value;
63+
element.textContent = isUndefined(value) ? '' : stringify(value);
6464
});
6565
};
6666
}

src/ng/interpolate.js

-17
Original file line numberDiff line numberDiff line change
@@ -111,23 +111,6 @@ function $InterpolateProvider() {
111111
replace(escapedEndRegexp, endSymbol);
112112
}
113113

114-
function stringify(value) {
115-
if (value == null) { // null || undefined
116-
return '';
117-
}
118-
switch (typeof value) {
119-
case 'string':
120-
break;
121-
case 'number':
122-
value = '' + value;
123-
break;
124-
default:
125-
value = toJson(value);
126-
}
127-
128-
return value;
129-
}
130-
131114
//TODO: this is the same as the constantWatchDelegate in parse.js
132115
function constantWatchDelegate(scope, listener, objectEquality, constantInterp) {
133116
var unwatch;

test/ng/directive/ngBindSpec.js

+9
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ describe('ngBind*', function() {
4646
expect(element.text()).toEqual('-0false');
4747
}));
4848

49+
they('should jsonify $prop', [[{a: 1}, '{"a":1}'], [true, 'true'], [false, 'false']], function(prop) {
50+
inject(function($rootScope, $compile) {
51+
$rootScope.bind = prop[0];
52+
element = $compile('<div ng-bind="bind"></div>')($rootScope);
53+
$rootScope.$digest();
54+
expect(element.text()).toEqual(prop[1]);
55+
});
56+
});
57+
4958
it('should one-time bind if the expression starts with two colons', inject(function($rootScope, $compile) {
5059
element = $compile('<div ng-bind="::a"></div>')($rootScope);
5160
$rootScope.a = 'lucas';

0 commit comments

Comments
 (0)